sim_codec_bridge/
canonical.rs1use std::sync::Arc;
2
3use sim_codec::{
4 DecodeBudget, Decoder, DomainCodecLib, Encoder, Input, Output, ReadCx, domain_input_text,
5};
6use sim_kernel::{CodecId, Error, Expr, Lib, LibManifest, Linker, LoadCx, Result, Symbol, WriteCx};
7
8use crate::{BridgeBook, decode_bridge_text, encode_bridge_text, expr_to_packet, packet_to_expr};
9
10pub struct BridgeCodec;
12
13impl Decoder for BridgeCodec {
14 fn decode(&self, cx: &mut ReadCx<'_>, input: Input) -> Result<Expr> {
15 let source = domain_input_text(cx.codec, input)?;
16 let budget = DecodeBudget::new(cx.limits);
17 budget.check_input_bytes(cx.codec, source.len())?;
18 let packet = decode_bridge_text(&source, &BridgeBook::standard()).map_err(|err| {
19 Error::CodecError {
20 codec: cx.codec,
21 message: err.to_string(),
22 }
23 })?;
24 Ok(packet_to_expr(&packet))
25 }
26}
27
28impl Encoder for BridgeCodec {
29 fn encode(&self, cx: &mut WriteCx<'_>, expr: &Expr) -> Result<Output> {
30 let packet = expr_to_packet(expr).map_err(|err| Error::CodecError {
31 codec: cx.codec,
32 message: err.to_string(),
33 })?;
34 encode_bridge_text(&packet, &BridgeBook::standard())
35 .map(Output::Text)
36 .map_err(|err| Error::CodecError {
37 codec: cx.codec,
38 message: err.to_string(),
39 })
40 }
41}
42
43pub struct BridgeCodecLib {
45 symbol: Symbol,
46 codec_id: CodecId,
47}
48
49impl BridgeCodecLib {
50 pub fn new(id: CodecId) -> Self {
52 Self {
53 symbol: Symbol::qualified("codec", "bridge"),
54 codec_id: id,
55 }
56 }
57
58 fn domain_lib(&self) -> DomainCodecLib {
59 DomainCodecLib::new(
60 self.symbol.clone(),
61 self.codec_id,
62 Arc::new(BridgeCodec),
63 Arc::new(BridgeCodec),
64 crate::bridge_packet_shape_symbol(),
65 )
66 }
67}
68
69impl Lib for BridgeCodecLib {
70 fn manifest(&self) -> LibManifest {
71 self.domain_lib().manifest()
72 }
73
74 fn load(&self, cx: &mut LoadCx, linker: &mut Linker<'_>) -> Result<()> {
75 self.domain_lib().load(cx, linker)
76 }
77}