sim_codec_bitwise_base64/
codec.rs1use std::sync::Arc;
8
9use sim_codec::{
10 CodecDefaultDecode, CodecRuntime, Decoder, Encoder, Input, LocatedDecoder, LocatedEncoder,
11 Output, ReadCx, TreeDecoder, TreeEncoder, codec_value, validate_expr_tree,
12};
13use sim_codec_binary_base64::{decode_base64_with_limits, encode_base64};
14use sim_kernel::{
15 AbiVersion, CodecId, DefaultFactory, Dependency, Error, Export, Expr, Lib, LibManifest,
16 LibTarget, Linker, LocatedExpr, LocatedExprTree, Result, Symbol, Version, WriteCx,
17};
18
19pub struct BitwiseBase64Codec;
28
29impl Decoder for BitwiseBase64Codec {
30 fn decode(&self, cx: &mut ReadCx<'_>, input: Input) -> Result<Expr> {
31 decode_tree(cx, input).map(|tree| tree.located().expr)
32 }
33}
34
35impl Encoder for BitwiseBase64Codec {
36 fn encode(&self, _cx: &mut WriteCx<'_>, expr: &Expr) -> Result<Output> {
37 let frame = sim_codec_bitwise::encode_frame(expr)?;
38 Ok(Output::Text(encode_base64(&frame.0)))
39 }
40}
41
42impl LocatedDecoder for BitwiseBase64Codec {
43 fn decode_located(
44 &self,
45 cx: &mut ReadCx<'_>,
46 input: Input,
47 _source_id: String,
48 ) -> Result<LocatedExpr> {
49 decode_tree(cx, input).map(|tree| tree.located())
50 }
51}
52
53impl LocatedEncoder for BitwiseBase64Codec {
54 fn encode_located(&self, cx: &mut WriteCx<'_>, expr: &LocatedExpr) -> Result<Output> {
55 let frame = sim_codec_bitwise::encode_located_frame(expr, cx.options.lossless_origin)?;
56 Ok(Output::Text(encode_base64(&frame.0)))
57 }
58}
59
60impl TreeDecoder for BitwiseBase64Codec {
61 fn decode_tree(
62 &self,
63 cx: &mut ReadCx<'_>,
64 input: Input,
65 _source_id: String,
66 ) -> Result<LocatedExprTree> {
67 decode_tree(cx, input)
68 }
69}
70
71impl TreeEncoder for BitwiseBase64Codec {
72 fn encode_tree(&self, cx: &mut WriteCx<'_>, expr: &LocatedExprTree) -> Result<Output> {
73 validate_expr_tree(cx.codec, expr)?;
74 let frame = sim_codec_bitwise::encode_located_tree_frame(expr, cx.options.lossless_origin)?;
75 Ok(Output::Text(encode_base64(&frame.0)))
76 }
77}
78
79fn decode_tree(cx: &mut ReadCx<'_>, input: Input) -> Result<LocatedExprTree> {
80 let text = input_text(cx.codec, input)?;
81 let bytes = decode_base64_with_limits(cx.codec, &text, cx.limits)?;
82 sim_codec_bitwise::decode_located_tree_frame_with_limits(
83 cx.codec,
84 &bytes,
85 sim_codec_bitwise::DecodeLimits::from(cx.limits),
86 )
87 .map(|(_, tree)| tree)
88}
89
90fn input_text(codec: CodecId, input: Input) -> Result<String> {
91 match input {
92 Input::Text(text) => Ok(text),
93 Input::Bytes(bytes) => String::from_utf8(bytes).map_err(|err| Error::CodecError {
94 codec,
95 message: format!("bitwise-base64 input is not valid UTF-8: {err}"),
96 }),
97 }
98}
99
100pub struct BitwiseBase64CodecLib {
106 symbol: Symbol,
107 codec_id: CodecId,
108}
109
110impl BitwiseBase64CodecLib {
111 pub fn new(id: CodecId) -> Self {
114 Self {
115 symbol: Symbol::qualified("codec", "bitwise-base64"),
116 codec_id: id,
117 }
118 }
119}
120
121impl Lib for BitwiseBase64CodecLib {
122 fn manifest(&self) -> LibManifest {
123 LibManifest {
124 id: self.symbol.clone(),
125 version: Version(env!("CARGO_PKG_VERSION").to_owned()),
126 abi: AbiVersion { major: 0, minor: 1 },
127 target: LibTarget::HostRegistered,
128 requires: Vec::<Dependency>::new(),
129 capabilities: Vec::new(),
130 exports: vec![Export::Codec {
131 symbol: self.symbol.clone(),
132 codec_id: Some(self.codec_id),
133 }],
134 }
135 }
136
137 fn load(&self, _cx: &mut sim_kernel::LoadCx, linker: &mut Linker) -> Result<()> {
138 let _factory = DefaultFactory;
139 let expr_shape = sim_codec::resolve_expr_shape(
140 linker,
141 &Symbol::qualified("codec", "BitwiseBase64Text"),
142 )?;
143 let options_shape = sim_codec::resolve_options_shape(linker)?;
144
145 linker.codec_value(
146 self.symbol.clone(),
147 codec_value(CodecRuntime {
148 id: self.codec_id,
149 symbol: self.symbol.clone(),
150 decoder: Some(Arc::new(BitwiseBase64Codec)),
151 located_decoder: Some(Arc::new(BitwiseBase64Codec)),
152 tree_decoder: Some(Arc::new(BitwiseBase64Codec)),
153 encoder: Some(Arc::new(BitwiseBase64Codec)),
154 located_encoder: Some(Arc::new(BitwiseBase64Codec)),
155 tree_encoder: Some(Arc::new(BitwiseBase64Codec)),
156 expr_shape,
157 options_shape,
158 default_decode: CodecDefaultDecode::Datum,
159 }),
160 )?;
161 Ok(())
162 }
163}