Skip to content
This repository was archived by the owner on Jun 18, 2026. It is now read-only.

Commit 5429783

Browse files
Fix missing space after type references in schema serialization
When serializing Schema::Type variants (via #[facet(other)] with the tag was written with no payload. This caused output like @Map(@ColumnName@optional(@FieldDef)) instead of the correct @Map(@ColumnName @optional(@FieldDef)). Implement finish_variant_tag_unit_payload to clear the flag when a variant tag completes without a payload. Fixes #54
1 parent 3a1886d commit 5429783

4 files changed

Lines changed: 68 additions & 27 deletions

File tree

Cargo.lock

Lines changed: 27 additions & 27 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,4 @@ lto = "thin"
6868
# facet-dessert = { path = "../facet/facet-dessert" }
6969
# facet-solver = { path = "../facet/facet-solver" }
7070
# facet-json = { path = "../facet/facet-json" }
71+
# facet-testhelpers = { path = "../facet/facet-testhelpers" }

crates/facet-styx/src/serializer.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,15 @@ impl FormatSerializer for StyxSerializer {
388388
Ok(())
389389
}
390390

391+
fn finish_variant_tag_unit_payload(&mut self) -> Result<(), Self::Error> {
392+
trace!("finish_variant_tag_unit_payload");
393+
// Clear the flags that were set by write_variant_tag, since no payload follows.
394+
// This ensures the next value gets proper spacing.
395+
self.just_wrote_tag = false;
396+
self.writer.clear_skip_before_value();
397+
Ok(())
398+
}
399+
391400
fn raw_serialize_shape(&self) -> Option<&'static facet_core::Shape> {
392401
Some(crate::RawStyx::SHAPE)
393402
}

crates/facet-styx/src/tests.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,3 +697,34 @@ fn test_bare_number_is_string() {
697697
let result: Config = from_str(input).unwrap();
698698
assert_eq!(result.port, "8080");
699699
}
700+
701+
/// Test that @map(@TypeRef @optional(@OtherType)) has proper spacing between type references.
702+
/// This is a regression test for a bug where type references (via #[facet(other)] variants)
703+
/// didn't get proper spacing when serialized in maps.
704+
#[test]
705+
fn test_map_type_ref_spacing() {
706+
use crate::schema_types::{Documented, MapSchema, OptionalSchema, Schema};
707+
708+
// Create a map with a type reference key and optional type reference value
709+
// This mimics: IndexMap<ColumnName, Option<FieldDef>> -> @map(@ColumnName @optional(@FieldDef))
710+
let map_schema = Schema::Map(MapSchema(vec![
711+
Documented::new(Schema::Type {
712+
name: Some("ColumnName".to_string()),
713+
}),
714+
Documented::new(Schema::Optional(OptionalSchema((Documented::new(
715+
Box::new(Schema::Type {
716+
name: Some("FieldDef".to_string()),
717+
}),
718+
),)))),
719+
]));
720+
721+
let output = to_string(&map_schema).unwrap();
722+
eprintln!("Output: {}", output);
723+
724+
// Check that there's a space between @ColumnName and @optional
725+
assert!(
726+
output.contains("@ColumnName @optional"),
727+
"Expected space between @ColumnName and @optional, got: {}",
728+
output
729+
);
730+
}

0 commit comments

Comments
 (0)