A better Rust ATProto crate

fix: ensure deterministic field ordering in builder state types #9

open opened by rwell.org targeting main from rwell.org/jacquard: fix-builder-determinism
Labels

None yet.

assignee

None yet.

Participants 1
AT URI
at://did:plc:vozr2os4b4sxrxr6opde5js5/sh.tangled.repo.pull/3miofv3ulqm22
+48 -45
Diff #0
+4 -2
crates/jacquard-lexicon/src/codegen/builder_gen/state_mod.rs
··· 13 13 use crate::codegen::utils::make_ident; 14 14 15 15 /// Information about a required field for builder state generation 16 - #[derive(Debug, Clone, Hash, PartialEq, Eq)] 16 + #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] 17 17 pub struct RequiredField { 18 18 /// Field name (snake_case) 19 19 pub name_snake: SmolStr, ··· 47 47 }) 48 48 .collect(); 49 49 50 - set.into_iter().collect() 50 + let mut fields: Vec<_> = set.into_iter().collect(); 51 + fields.sort(); 52 + fields 51 53 } 52 54 53 55 /// Generate the complete state module for a builder
+44 -43
crates/jacquard-lexicon/src/codegen/builder_gen/tests.rs
··· 46 46 let _parsed: syn::File = syn::parse2(tokens).expect("Generated code should parse"); 47 47 } 48 48 49 - // TODO: re-enable these tests once i have time to get them to properly check and not be order-dependent 50 - // #[test] 51 - // fn test_collect_required_fields_object() { 52 - // let obj = LexObject { 53 - // description: None, 54 - // required: Some(vec![ 55 - // SmolStr::new_static("foo"), 56 - // SmolStr::new_static("barBaz"), 57 - // ]), 58 - // nullable: None, 59 - // properties: Default::default(), 60 - // }; 61 - 62 - // let schema = BuilderSchema::Object(&obj); 63 - // let fields = collect_required_fields(&schema); 64 - 65 - // assert_eq!(fields.len(), 2); 66 - // assert_eq!(fields[0].name_snake, "foo"); 67 - // assert_eq!(fields[0].name_pascal, "Foo"); 68 - // assert_eq!(fields[1].name_snake, "bar_baz"); 69 - // assert_eq!(fields[1].name_pascal, "BarBaz"); 70 - // } 71 - 72 - // #[test] 73 - // fn test_collect_required_fields_parameters() { 74 - // let params = LexXrpcParameters { 75 - // description: None, 76 - // required: Some(vec![ 77 - // SmolStr::new_static("limit"), 78 - // SmolStr::new_static("cursor"), 79 - // ]), 80 - // properties: Default::default(), 81 - // }; 82 - 83 - // let schema = BuilderSchema::Parameters(&params); 84 - // let fields = collect_required_fields(&schema); 85 - 86 - // assert_eq!(fields.len(), 2); 87 - // assert_eq!(fields[1].name_snake, "limit"); 88 - // assert_eq!(fields[1].name_pascal, "Limit"); 89 - // assert_eq!(fields[0].name_snake, "cursor"); 90 - // assert_eq!(fields[0].name_pascal, "Cursor"); 91 - // } 49 + #[test] 50 + fn test_collect_required_fields_object() { 51 + let obj = LexObject { 52 + description: None, 53 + required: Some(vec![ 54 + SmolStr::new_static("foo"), 55 + SmolStr::new_static("barBaz"), 56 + ]), 57 + nullable: None, 58 + properties: Default::default(), 59 + }; 60 + 61 + let schema = BuilderSchema::Object(&obj); 62 + let fields = collect_required_fields(&schema); 63 + 64 + assert_eq!(fields.len(), 2); 65 + // bar_baz comes before foo alphabetically 66 + assert_eq!(fields[0].name_snake, "bar_baz"); 67 + assert_eq!(fields[0].name_pascal, "BarBaz"); 68 + assert_eq!(fields[1].name_snake, "foo"); 69 + assert_eq!(fields[1].name_pascal, "Foo"); 70 + } 71 + 72 + #[test] 73 + fn test_collect_required_fields_parameters() { 74 + let params = LexXrpcParameters { 75 + description: None, 76 + required: Some(vec![ 77 + SmolStr::new_static("limit"), 78 + SmolStr::new_static("cursor"), 79 + ]), 80 + properties: Default::default(), 81 + }; 82 + 83 + let schema = BuilderSchema::Parameters(&params); 84 + let fields = collect_required_fields(&schema); 85 + 86 + assert_eq!(fields.len(), 2); 87 + // cursor comes before limit alphabetically 88 + assert_eq!(fields[0].name_snake, "cursor"); 89 + assert_eq!(fields[0].name_pascal, "Cursor"); 90 + assert_eq!(fields[1].name_snake, "limit"); 91 + assert_eq!(fields[1].name_pascal, "Limit"); 92 + } 92 93 93 94 #[test] 94 95 fn test_state_module_generation() {

History

1 round 0 comments
sign up or login to add to the discussion
rwell.org submitted #0
1 commit
expand
fix: ensure deterministic field ordering in builder state types
no conflicts, ready to merge
expand 0 comments