crdt_graph/flatbuffers/
string.rs1use crate::graph::UpdateOperation;
2use crate::types::string;
3use flatbuffers::FlatBufferBuilder;
4
5use super::crdt_graph_with_str_data_generated::crdt_graph::fb_str;
6use super::{uuid_from_fb, DecodeError};
7
8pub fn encode_operation(op: &string::Operation) -> Vec<u8> {
14 let mut builder = FlatBufferBuilder::new();
15 let op_offset = write_update_operation(&mut builder, op);
16
17 let ops_vec = builder.create_vector(&[op_offset]);
18 let log = fb_str::OperationLog::create(
19 &mut builder,
20 &fb_str::OperationLogArgs {
21 operations: Some(ops_vec),
22 },
23 );
24 builder.finish(log, Some("CRD3"));
25 builder.finished_data().to_vec()
26}
27
28pub fn encode_operation_log(ops: &[string::Operation]) -> Vec<u8> {
30 let mut builder = FlatBufferBuilder::new();
31
32 let offsets: Vec<_> = ops
33 .iter()
34 .map(|op| write_update_operation(&mut builder, op))
35 .collect();
36
37 let ops_vec = builder.create_vector(&offsets);
38 let log = fb_str::OperationLog::create(
39 &mut builder,
40 &fb_str::OperationLogArgs {
41 operations: Some(ops_vec),
42 },
43 );
44 builder.finish(log, Some("CRD3"));
45 builder.finished_data().to_vec()
46}
47
48fn write_update_operation<'bldr, A: flatbuffers::Allocator + 'bldr>(
49 builder: &mut FlatBufferBuilder<'bldr, A>,
50 op: &string::Operation,
51) -> flatbuffers::WIPOffset<fb_str::UpdateOperation<'bldr>> {
52 match op {
53 UpdateOperation::AddVertex(v) => {
54 let id = fb_str::Uuid(*v.id.as_bytes());
55 let data = v.data.as_ref().map(|d| builder.create_string(d));
56 let inner = fb_str::AddVertex::create(
57 builder,
58 &fb_str::AddVertexArgs {
59 id: Some(&id),
60 data,
61 },
62 );
63 fb_str::UpdateOperation::create(
64 builder,
65 &fb_str::UpdateOperationArgs {
66 operation_type: fb_str::Operation::AddVertex,
67 operation: Some(inner.as_union_value()),
68 },
69 )
70 }
71 UpdateOperation::RemoveVertex(v) => {
72 let id = fb_str::Uuid(*v.id.as_bytes());
73 let add_vertex_id = fb_str::Uuid(*v.add_vertex_id.as_bytes());
74 let inner = fb_str::RemoveVertex::create(
75 builder,
76 &fb_str::RemoveVertexArgs {
77 id: Some(&id),
78 add_vertex_id: Some(&add_vertex_id),
79 },
80 );
81 fb_str::UpdateOperation::create(
82 builder,
83 &fb_str::UpdateOperationArgs {
84 operation_type: fb_str::Operation::RemoveVertex,
85 operation: Some(inner.as_union_value()),
86 },
87 )
88 }
89 UpdateOperation::AddEdge(e) => {
90 let id = fb_str::Uuid(*e.id.as_bytes());
91 let source = fb_str::Uuid(*e.source.as_bytes());
92 let target = fb_str::Uuid(*e.target.as_bytes());
93 let data = e.data.as_ref().map(|d| builder.create_string(d));
94 let inner = fb_str::AddEdge::create(
95 builder,
96 &fb_str::AddEdgeArgs {
97 id: Some(&id),
98 source: Some(&source),
99 target: Some(&target),
100 data,
101 },
102 );
103 fb_str::UpdateOperation::create(
104 builder,
105 &fb_str::UpdateOperationArgs {
106 operation_type: fb_str::Operation::AddEdge,
107 operation: Some(inner.as_union_value()),
108 },
109 )
110 }
111 UpdateOperation::RemoveEdge(e) => {
112 let id = fb_str::Uuid(*e.id.as_bytes());
113 let add_edge_id = fb_str::Uuid(*e.add_edge_id.as_bytes());
114 let inner = fb_str::RemoveEdge::create(
115 builder,
116 &fb_str::RemoveEdgeArgs {
117 id: Some(&id),
118 add_edge_id: Some(&add_edge_id),
119 },
120 );
121 fb_str::UpdateOperation::create(
122 builder,
123 &fb_str::UpdateOperationArgs {
124 operation_type: fb_str::Operation::RemoveEdge,
125 operation: Some(inner.as_union_value()),
126 },
127 )
128 }
129 }
130}
131
132pub fn decode_operation(buf: &[u8]) -> Result<string::Operation, DecodeError> {
138 let ops = decode_operation_log(buf)?;
139 ops.into_iter()
140 .next()
141 .ok_or(DecodeError::UnknownOperationType)
142}
143
144pub fn decode_operation_log(buf: &[u8]) -> Result<Vec<string::Operation>, DecodeError> {
146 let log = fb_str::root_as_operation_log(buf)?;
147 let operations = log.operations();
148
149 let mut result = Vec::with_capacity(operations.len());
150 for fb_op in operations.iter() {
151 let op = read_update_operation(&fb_op)?;
152 result.push(op);
153 }
154 Ok(result)
155}
156
157fn read_update_operation(
158 fb_op: &fb_str::UpdateOperation<'_>,
159) -> Result<string::Operation, DecodeError> {
160 match fb_op.operation_type() {
161 fb_str::Operation::AddVertex => {
162 let v = fb_op
163 .operation_as_add_vertex()
164 .ok_or(DecodeError::UnknownOperationType)?;
165 Ok(UpdateOperation::AddVertex(string::AddVertex {
166 id: uuid_from_fb(&v.id().0),
167 data: v.data().map(|s| s.to_owned()),
168 }))
169 }
170 fb_str::Operation::RemoveVertex => {
171 let v = fb_op
172 .operation_as_remove_vertex()
173 .ok_or(DecodeError::UnknownOperationType)?;
174 Ok(UpdateOperation::RemoveVertex(crate::types::RemoveVertex {
175 id: uuid_from_fb(&v.id().0),
176 add_vertex_id: uuid_from_fb(&v.add_vertex_id().0),
177 }))
178 }
179 fb_str::Operation::AddEdge => {
180 let e = fb_op
181 .operation_as_add_edge()
182 .ok_or(DecodeError::UnknownOperationType)?;
183 Ok(UpdateOperation::AddEdge(string::AddEdge {
184 id: uuid_from_fb(&e.id().0),
185 source: uuid_from_fb(&e.source().0),
186 target: uuid_from_fb(&e.target().0),
187 data: e.data().map(|s| s.to_owned()),
188 }))
189 }
190 fb_str::Operation::RemoveEdge => {
191 let e = fb_op
192 .operation_as_remove_edge()
193 .ok_or(DecodeError::UnknownOperationType)?;
194 Ok(UpdateOperation::RemoveEdge(crate::types::RemoveEdge {
195 id: uuid_from_fb(&e.id().0),
196 add_edge_id: uuid_from_fb(&e.add_edge_id().0),
197 }))
198 }
199 _ => Err(DecodeError::UnknownOperationType),
200 }
201}