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