Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Do not produce useless match cases unit enums
Given enums like these: ```rust enum Foo { A(u16), B, C(i32, i32), } enum Bar { A, B, C, } ``` serialise derive produces something like these: ```rust // Recursive expansion of borsh::BorshSerialize macro // =================================================== impl borsh::ser::BorshSerialize for Foo { fn serialize<W: borsh::io::Write>( &self, writer: &mut W, ) -> ::core::result::Result<(), borsh::io::Error> { let variant_idx: u8 = match self { Foo::A(..) => 0u8, Foo::B => 1u8, Foo::C(..) => 2u8, }; writer.write_all(&variant_idx.to_le_bytes())?; match self { Foo::A(id0) => { borsh::BorshSerialize::serialize(id0, writer)?; } Foo::B => {} Foo::C(id0, id1) => { borsh::BorshSerialize::serialize(id0, writer)?; borsh::BorshSerialize::serialize(id1, writer)?; } } Ok(()) } } // Recursive expansion of borsh::BorshSerialize macro // =================================================== impl borsh::ser::BorshSerialize for Bar { fn serialize<W: borsh::io::Write>( &self, writer: &mut W, ) -> ::core::result::Result<(), borsh::io::Error> { let variant_idx: u8 = match self { Bar::A => 0u8, Bar::B => 1u8, Bar::C => 2u8, }; writer.write_all(&variant_idx.to_le_bytes())?; match self { Bar::A => {} Bar::B => {} Bar::C => {} } Ok(()) } } ``` Notably in `Bar` case, the whole `match self` is useless because there's nothing left to serialise. With this patch, the derives now look like this: ```rust // Recursive expansion of borsh::BorshSerialize macro // =================================================== impl borsh::ser::BorshSerialize for Foo { fn serialize<W: borsh::io::Write>( &self, writer: &mut W, ) -> ::core::result::Result<(), borsh::io::Error> { let variant_idx: u8 = match self { Foo::A(..) => 0u8, Foo::B => 1u8, Foo::C(..) => 2u8, }; writer.write_all(&variant_idx.to_le_bytes())?; match self { Foo::A(id0) => { borsh::BorshSerialize::serialize(id0, writer)?; } Foo::C(id0, id1) => { borsh::BorshSerialize::serialize(id0, writer)?; borsh::BorshSerialize::serialize(id1, writer)?; } _ => {} } Ok(()) } } // Recursive expansion of borsh::BorshSerialize macro // =================================================== impl borsh::ser::BorshSerialize for Bar { fn serialize<W: borsh::io::Write>( &self, writer: &mut W, ) -> ::core::result::Result<(), borsh::io::Error> { let variant_idx: u8 = match self { Bar::A => 0u8, Bar::B => 1u8, Bar::C => 2u8, }; writer.write_all(&variant_idx.to_le_bytes())?; Ok(()) } } ``` Notably, the whole `match self` is gone for `Bar`. For `Foo`, any unit field cases are now inside a `_ => {}` catch-all. What's the point? Well, it's just nice to produce less for compiler to deal with, reducing upstream build times. Further, it makes it much nicer for anyone reading/copying the expanded macros. However patch this does add some amount of code complexity so it's up to the maintainers to decide if it's worth taking.
- Loading branch information