kb-core: hotfix Inline serde schema (struct variants)
`#[serde(tag = "kind")]` rejects newtype variants whose payload is not a
struct, so 4 of 5 `Inline` variants (`Text(String)`, `Code(String)`,
`Strong(Vec<…>)`, `Emph(Vec<…>)`) failed to serialize at runtime — only
`Link { text, href }` worked. Convert every variant to struct form so the
internally-tagged shape is well-formed and round-trips through JSON.
Add `inline_serde_round_trip` covering all five variants. Per design §9,
this is a wire-schema migration; no `docs/wire-schema/v1/*.json` change
required since `Inline` is not directly referenced there. Callers in
kb-parse-md follow in the next commit.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -100,11 +100,11 @@ pub struct AudioRefBlock {
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "lowercase", tag = "kind")]
|
||||
pub enum Inline {
|
||||
Text(String),
|
||||
Code(String),
|
||||
Text { text: String },
|
||||
Code { code: String },
|
||||
Link { text: String, href: String },
|
||||
Strong(Vec<Inline>),
|
||||
Emph(Vec<Inline>),
|
||||
Strong { children: Vec<Inline> },
|
||||
Emph { children: Vec<Inline> },
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
@@ -175,3 +175,37 @@ pub struct TranscriptSegment {
|
||||
pub speaker: Option<String>,
|
||||
pub confidence: Option<f32>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
/// Each `Inline` variant must serialize and deserialize cleanly under
|
||||
/// the internally-tagged representation. Newtype-with-primitive variants
|
||||
/// (`Text(String)`, `Code(String)`, `Strong(Vec<…>)`, `Emph(Vec<…>)`)
|
||||
/// previously failed at serde runtime because `tag = "kind"` cannot
|
||||
/// describe a newtype carrying a non-struct value. The struct-variant
|
||||
/// shape used here is the §9 schema migration.
|
||||
#[test]
|
||||
fn inline_serde_round_trip() {
|
||||
let cases = vec![
|
||||
Inline::Text { text: "hi".into() },
|
||||
Inline::Code { code: "x".into() },
|
||||
Inline::Link {
|
||||
text: "t".into(),
|
||||
href: "h".into(),
|
||||
},
|
||||
Inline::Strong {
|
||||
children: vec![Inline::Text { text: "bold".into() }],
|
||||
},
|
||||
Inline::Emph {
|
||||
children: vec![Inline::Text { text: "em".into() }],
|
||||
},
|
||||
];
|
||||
for c in cases {
|
||||
let s = serde_json::to_string(&c).expect("serialize");
|
||||
let back: Inline = serde_json::from_str(&s).expect("deserialize");
|
||||
assert_eq!(c, back);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user