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