sim_codec_bridge/
ownership.rs1use sim_kernel::{Error, Result};
2
3use crate::{BridgeBook, BridgePacket, decode_bridge_text, encode_bridge_text};
4
5#[derive(Clone, Debug, PartialEq, Eq)]
7pub enum OwnedSpan {
8 Structural(String),
10 Frame {
12 id: String,
14 text: String,
16 },
17 Part {
19 id: String,
21 kind: String,
23 text: String,
25 },
26 Fence {
28 id: String,
30 text: String,
32 },
33}
34
35impl OwnedSpan {
36 pub fn rendered_text(&self) -> &str {
38 match self {
39 Self::Structural(text) => text,
40 Self::Frame { text, .. } | Self::Part { text, .. } | Self::Fence { text, .. } => text,
41 }
42 }
43}
44
45pub fn assert_roundtrip(packet: &BridgePacket, book: &BridgeBook) -> Result<()> {
47 let text = encode_bridge_text(packet, book)?;
48 let decoded = decode_bridge_text(&text, book)?;
49 if decoded != *packet {
50 return Err(Error::Eval("bridge roundtrip mismatch".to_owned()));
51 }
52 Ok(())
53}
54
55pub fn assert_total_ownership(rendered: &str, spans: &[OwnedSpan]) -> Result<()> {
57 let mut cursor = 0usize;
58 for span in spans {
59 let text = span.rendered_text();
60 if !rendered[cursor..].starts_with(text) {
61 return Err(Error::Eval(format!(
62 "bridge render has unowned bytes at {cursor}"
63 )));
64 }
65 cursor += text.len();
66 }
67 if cursor != rendered.len() {
68 return Err(Error::Eval(
69 "bridge render has unowned trailing bytes".to_owned(),
70 ));
71 }
72 Ok(())
73}