sim_codec/implementation/
domain.rs1use std::sync::Arc;
10
11use sim_kernel::{
12 AbiVersion, CodecId, DefaultFactory, Dependency, Export, Factory, Lib, LibManifest, LibTarget,
13 Linker, LoadCx, Result, ShapeRef, Symbol, Version,
14};
15
16use crate::{CodecDefaultDecode, CodecRuntime, Decoder, Encoder, Input, codec_value};
17
18pub fn domain_input_text(codec: CodecId, input: Input) -> Result<String> {
21 input.into_string_for(codec)
22}
23
24pub fn resolve_expr_shape(linker: &Linker, primary: &Symbol) -> Result<ShapeRef> {
29 let nil = DefaultFactory.nil()?;
30 Ok(linker
31 .registry()
32 .shape_by_symbol(primary)
33 .or_else(|| {
34 linker
35 .registry()
36 .shape_by_symbol(&Symbol::qualified("core", "Expr"))
37 })
38 .or_else(|| {
39 linker
40 .registry()
41 .shape_by_symbol(&Symbol::qualified("core", "Any"))
42 })
43 .cloned()
44 .unwrap_or(nil))
45}
46
47pub fn resolve_options_shape(linker: &Linker) -> Result<ShapeRef> {
50 let nil = DefaultFactory.nil()?;
51 Ok(linker
52 .registry()
53 .shape_by_symbol(&Symbol::qualified("core", "EncodeOptions"))
54 .or_else(|| {
55 linker
56 .registry()
57 .shape_by_symbol(&Symbol::qualified("core", "Any"))
58 })
59 .cloned()
60 .unwrap_or(nil))
61}
62
63pub struct DomainCodecLib {
66 symbol: Symbol,
67 codec_id: CodecId,
68 decoder: Arc<dyn Decoder>,
69 encoder: Arc<dyn Encoder>,
70 expr_shape_symbol: Symbol,
71 shapes: Vec<(Symbol, ShapeRef)>,
72}
73
74impl DomainCodecLib {
75 pub fn new(
79 symbol: Symbol,
80 codec_id: CodecId,
81 decoder: Arc<dyn Decoder>,
82 encoder: Arc<dyn Encoder>,
83 expr_shape_symbol: Symbol,
84 ) -> Self {
85 Self {
86 symbol,
87 codec_id,
88 decoder,
89 encoder,
90 expr_shape_symbol,
91 shapes: Vec::new(),
92 }
93 }
94
95 pub fn with_shapes(mut self, shapes: Vec<(Symbol, ShapeRef)>) -> Self {
98 self.shapes = shapes;
99 self
100 }
101}
102
103impl Lib for DomainCodecLib {
104 fn manifest(&self) -> LibManifest {
105 let mut exports: Vec<Export> = self
106 .shapes
107 .iter()
108 .map(|(symbol, _)| Export::Shape {
109 symbol: symbol.clone(),
110 shape_id: None,
111 })
112 .collect();
113 exports.push(Export::Codec {
114 symbol: self.symbol.clone(),
115 codec_id: Some(self.codec_id),
116 });
117 LibManifest {
118 id: self.symbol.clone(),
119 version: Version(env!("CARGO_PKG_VERSION").to_owned()),
120 abi: AbiVersion { major: 0, minor: 1 },
121 target: LibTarget::HostRegistered,
122 requires: Vec::<Dependency>::new(),
123 capabilities: Vec::new(),
124 exports,
125 }
126 }
127
128 fn load(&self, _cx: &mut LoadCx, linker: &mut Linker<'_>) -> Result<()> {
129 for (symbol, shape) in &self.shapes {
130 linker.shape_value(symbol.clone(), shape.clone())?;
131 }
132 let nil = DefaultFactory.nil()?;
133 let expr_shape = self
134 .shapes
135 .iter()
136 .find(|(symbol, _)| symbol == &self.expr_shape_symbol)
137 .map(|(_, shape)| shape.clone())
138 .or_else(|| {
139 linker
140 .registry()
141 .shape_by_symbol(&self.expr_shape_symbol)
142 .cloned()
143 })
144 .or_else(|| {
145 linker
146 .registry()
147 .shape_by_symbol(&Symbol::qualified("core", "Expr"))
148 .cloned()
149 })
150 .or_else(|| {
151 linker
152 .registry()
153 .shape_by_symbol(&Symbol::qualified("core", "Any"))
154 .cloned()
155 })
156 .unwrap_or_else(|| nil.clone());
157 linker.codec_value(
158 self.symbol.clone(),
159 codec_value(CodecRuntime {
160 id: self.codec_id,
161 symbol: self.symbol.clone(),
162 decoder: Some(self.decoder.clone()),
163 located_decoder: None,
164 tree_decoder: None,
165 encoder: Some(self.encoder.clone()),
166 located_encoder: None,
167 tree_encoder: None,
168 expr_shape,
169 options_shape: nil,
170 default_decode: CodecDefaultDecode::Datum,
171 }),
172 )?;
173 Ok(())
174 }
175}