plexus_serde/
capability.rs1use crate::plexus_generated::plexus as fb;
2use crate::{
3 CapabilityOrderingContract, CapabilitySemver, CapabilityVersionRange, EngineCapabilityDecl,
4 OpOrderingDecl, SerdeError,
5};
6use flatbuffers::FlatBufferBuilder;
7
8fn to_fb_ordering_contract(contract: CapabilityOrderingContract) -> fb::CapabilityOrderingContract {
9 match contract {
10 CapabilityOrderingContract::EngineDefinedStable => {
11 fb::CapabilityOrderingContract::engine_defined_stable
12 }
13 CapabilityOrderingContract::StablePassThrough => {
14 fb::CapabilityOrderingContract::stable_pass_through
15 }
16 CapabilityOrderingContract::FanOutDeterministicPerInput => {
17 fb::CapabilityOrderingContract::fan_out_deterministic_per_input
18 }
19 CapabilityOrderingContract::DeterministicSortStableTies => {
20 fb::CapabilityOrderingContract::deterministic_sort_stable_ties
21 }
22 CapabilityOrderingContract::UnspecifiedWithoutSort => {
23 fb::CapabilityOrderingContract::unspecified_without_sort
24 }
25 CapabilityOrderingContract::StableConcatOrUnspecifiedDistinct => {
26 fb::CapabilityOrderingContract::stable_concat_or_unspecified_distinct
27 }
28 CapabilityOrderingContract::ScoreDescStableTies => {
29 fb::CapabilityOrderingContract::score_desc_stable_ties
30 }
31 }
32}
33
34fn from_fb_ordering_contract(
35 contract: fb::CapabilityOrderingContract,
36) -> Result<CapabilityOrderingContract, SerdeError> {
37 Ok(match contract {
38 fb::CapabilityOrderingContract::engine_defined_stable => {
39 CapabilityOrderingContract::EngineDefinedStable
40 }
41 fb::CapabilityOrderingContract::stable_pass_through => {
42 CapabilityOrderingContract::StablePassThrough
43 }
44 fb::CapabilityOrderingContract::fan_out_deterministic_per_input => {
45 CapabilityOrderingContract::FanOutDeterministicPerInput
46 }
47 fb::CapabilityOrderingContract::deterministic_sort_stable_ties => {
48 CapabilityOrderingContract::DeterministicSortStableTies
49 }
50 fb::CapabilityOrderingContract::unspecified_without_sort => {
51 CapabilityOrderingContract::UnspecifiedWithoutSort
52 }
53 fb::CapabilityOrderingContract::stable_concat_or_unspecified_distinct => {
54 CapabilityOrderingContract::StableConcatOrUnspecifiedDistinct
55 }
56 fb::CapabilityOrderingContract::score_desc_stable_ties => {
57 CapabilityOrderingContract::ScoreDescStableTies
58 }
59 _ => {
60 return Err(SerdeError::Unsupported(
61 "unknown CapabilityOrderingContract enum value",
62 ))
63 }
64 })
65}
66
67pub fn serialize_engine_capability_decl(
68 decl: &EngineCapabilityDecl,
69) -> Result<Vec<u8>, SerdeError> {
70 let mut fbb = FlatBufferBuilder::new();
71 let version_range = fb::CapabilityVersionRange::create(
72 &mut fbb,
73 &fb::CapabilityVersionRangeArgs {
74 min_major: decl.version_range.min_supported.major,
75 min_minor: decl.version_range.min_supported.minor,
76 min_patch: decl.version_range.min_supported.patch,
77 max_major: decl.version_range.max_supported.major,
78 max_minor: decl.version_range.max_supported.minor,
79 max_patch: decl.version_range.max_supported.patch,
80 },
81 );
82
83 let supported_ops_strs = decl
84 .supported_ops
85 .iter()
86 .map(|x| fbb.create_string(x))
87 .collect::<Vec<_>>();
88 let supported_ops = fbb.create_vector(&supported_ops_strs);
89
90 let supported_exprs_strs = decl
91 .supported_exprs
92 .iter()
93 .map(|x| fbb.create_string(x))
94 .collect::<Vec<_>>();
95 let supported_exprs = fbb.create_vector(&supported_exprs_strs);
96
97 let op_ordering_offsets = decl
98 .op_ordering
99 .iter()
100 .map(|entry| {
101 let op = fbb.create_string(&entry.op);
102 fb::OpOrderingDecl::create(
103 &mut fbb,
104 &fb::OpOrderingDeclArgs {
105 op: Some(op),
106 contract: to_fb_ordering_contract(entry.contract),
107 },
108 )
109 })
110 .collect::<Vec<_>>();
111 let op_ordering = fbb.create_vector(&op_ordering_offsets);
112
113 let root = fb::EngineCapabilityDecl::create(
114 &mut fbb,
115 &fb::EngineCapabilityDeclArgs {
116 version_range: Some(version_range),
117 supported_ops: Some(supported_ops),
118 supported_exprs: Some(supported_exprs),
119 op_ordering: Some(op_ordering),
120 supports_graph_ref: decl.supports_graph_ref,
121 supports_multi_graph: decl.supports_multi_graph,
122 supports_graph_params: decl.supports_graph_params,
123 },
124 );
125 fbb.finish(root, None);
126 Ok(fbb.finished_data().to_vec())
127}
128
129pub fn deserialize_engine_capability_decl(
130 bytes: &[u8],
131) -> Result<EngineCapabilityDecl, SerdeError> {
132 let fb_decl = flatbuffers::root::<fb::EngineCapabilityDecl<'_>>(bytes)?;
133 let vr = fb_decl.version_range();
134 let version_range = CapabilityVersionRange {
135 min_supported: CapabilitySemver {
136 major: vr.min_major(),
137 minor: vr.min_minor(),
138 patch: vr.min_patch(),
139 },
140 max_supported: CapabilitySemver {
141 major: vr.max_major(),
142 minor: vr.max_minor(),
143 patch: vr.max_patch(),
144 },
145 };
146
147 let supported_ops = fb_decl
148 .supported_ops()
149 .map(|xs| (0..xs.len()).map(|i| xs.get(i).to_string()).collect())
150 .unwrap_or_default();
151 let supported_exprs = fb_decl
152 .supported_exprs()
153 .map(|xs| (0..xs.len()).map(|i| xs.get(i).to_string()).collect())
154 .unwrap_or_default();
155 let op_ordering = fb_decl
156 .op_ordering()
157 .map(|xs| {
158 (0..xs.len())
159 .map(|i| {
160 let x = xs.get(i);
161 let op = x
162 .op()
163 .ok_or(SerdeError::MissingField("OpOrderingDecl.op"))?
164 .to_string();
165 Ok(OpOrderingDecl {
166 op,
167 contract: from_fb_ordering_contract(x.contract())?,
168 })
169 })
170 .collect::<Result<Vec<_>, SerdeError>>()
171 })
172 .transpose()?
173 .unwrap_or_default();
174
175 Ok(EngineCapabilityDecl {
176 version_range,
177 supported_ops,
178 supported_exprs,
179 op_ordering,
180 supports_graph_ref: fb_decl.supports_graph_ref(),
181 supports_multi_graph: fb_decl.supports_multi_graph(),
182 supports_graph_params: fb_decl.supports_graph_params(),
183 })
184}