Skip to main content

nmp_threading/wire/
encode.rs

1use flatbuffers::{FlatBufferBuilder, WIPOffset};
2
3use crate::{ThreadEdge, ThreadPointer, ThreadingSnapshot, TimelineBlock};
4
5use super::fb;
6use super::THREADING_GRAPH_SCHEMA_VERSION;
7
8#[must_use]
9pub fn encode_threading_snapshot(snapshot: &ThreadingSnapshot) -> Vec<u8> {
10    let mut builder = FlatBufferBuilder::new();
11
12    let edges: Vec<WIPOffset<fb::ThreadEdge<'_>>> = snapshot
13        .edges
14        .iter()
15        .map(|edge| encode_edge(&mut builder, edge))
16        .collect();
17    let edges = builder.create_vector(&edges);
18
19    let blocks: Vec<WIPOffset<fb::TimelineBlockEntry<'_>>> = snapshot
20        .blocks
21        .iter()
22        .map(|block| encode_block(&mut builder, block))
23        .collect();
24    let blocks = builder.create_vector(&blocks);
25
26    let pending: Vec<WIPOffset<fb::BlockEventId<'_>>> = snapshot
27        .pending_ancestor_ids
28        .iter()
29        .map(|id| encode_id(&mut builder, id))
30        .collect();
31    let pending = builder.create_vector(&pending);
32
33    let root = fb::ThreadingSnapshot::create(
34        &mut builder,
35        &fb::ThreadingSnapshotArgs {
36            schema_version: THREADING_GRAPH_SCHEMA_VERSION,
37            edges: Some(edges),
38            blocks: Some(blocks),
39            pending_ancestor_ids: Some(pending),
40        },
41    );
42    fb::finish_threading_snapshot_buffer(&mut builder, root);
43    builder.finished_data().to_vec()
44}
45
46fn encode_edge<'bldr>(
47    builder: &mut FlatBufferBuilder<'bldr>,
48    edge: &ThreadEdge,
49) -> WIPOffset<fb::ThreadEdge<'bldr>> {
50    let event_id = builder.create_string(&edge.event_id);
51    let author_pubkey = builder.create_string(&edge.author_pubkey);
52    let parent = edge.parent.as_ref().map(|p| encode_pointer(builder, p));
53    let root = edge.root.as_ref().map(|p| encode_pointer(builder, p));
54    let parent_author_pubkey = edge
55        .parent_author_pubkey
56        .as_ref()
57        .map(|p| builder.create_string(p));
58    fb::ThreadEdge::create(
59        builder,
60        &fb::ThreadEdgeArgs {
61            event_id: Some(event_id),
62            author_pubkey: Some(author_pubkey),
63            kind: edge.kind,
64            created_at: edge.created_at,
65            parent,
66            root,
67            parent_author_pubkey,
68        },
69    )
70}
71
72fn encode_block<'bldr>(
73    builder: &mut FlatBufferBuilder<'bldr>,
74    block: &TimelineBlock,
75) -> WIPOffset<fb::TimelineBlockEntry<'bldr>> {
76    match block {
77        TimelineBlock::Standalone { id, root } => {
78            let standalone_id = builder.create_string(id);
79            let standalone_root = root.as_ref().map(|p| encode_pointer(builder, p));
80            fb::TimelineBlockEntry::create(
81                builder,
82                &fb::TimelineBlockEntryArgs {
83                    kind: fb::TimelineBlockKind::Standalone,
84                    standalone_id: Some(standalone_id),
85                    standalone_root,
86                    module_event_ids: None,
87                    module_has_gap: false,
88                    module_root: None,
89                },
90            )
91        }
92        TimelineBlock::Module {
93            events,
94            has_gap,
95            root,
96        } => {
97            let ids: Vec<WIPOffset<fb::BlockEventId<'_>>> =
98                events.iter().map(|id| encode_id(builder, id)).collect();
99            let module_event_ids = builder.create_vector(&ids);
100            let module_root = root.as_ref().map(|p| encode_pointer(builder, p));
101            fb::TimelineBlockEntry::create(
102                builder,
103                &fb::TimelineBlockEntryArgs {
104                    kind: fb::TimelineBlockKind::Module,
105                    standalone_id: None,
106                    standalone_root: None,
107                    module_event_ids: Some(module_event_ids),
108                    module_has_gap: *has_gap,
109                    module_root,
110                },
111            )
112        }
113    }
114}
115
116fn encode_pointer<'bldr>(
117    builder: &mut FlatBufferBuilder<'bldr>,
118    pointer: &ThreadPointer,
119) -> WIPOffset<fb::ThreadPointer<'bldr>> {
120    match pointer {
121        ThreadPointer::Event { id, relay, kind } => {
122            let id = builder.create_string(id);
123            let relay = relay.as_ref().map(|r| builder.create_string(r));
124            fb::ThreadPointer::create(
125                builder,
126                &fb::ThreadPointerArgs {
127                    kind: fb::ThreadPointerKind::Event,
128                    id: Some(id),
129                    coord: None,
130                    uri: None,
131                    relay,
132                    has_kind_num: kind.is_some(),
133                    kind_num: kind.unwrap_or_default(),
134                },
135            )
136        }
137        ThreadPointer::Address { coord, relay, kind } => {
138            let coord = builder.create_string(coord);
139            let relay = relay.as_ref().map(|r| builder.create_string(r));
140            fb::ThreadPointer::create(
141                builder,
142                &fb::ThreadPointerArgs {
143                    kind: fb::ThreadPointerKind::Address,
144                    id: None,
145                    coord: Some(coord),
146                    uri: None,
147                    relay,
148                    has_kind_num: kind.is_some(),
149                    kind_num: kind.unwrap_or_default(),
150                },
151            )
152        }
153        ThreadPointer::External { uri } => {
154            let uri = builder.create_string(uri);
155            fb::ThreadPointer::create(
156                builder,
157                &fb::ThreadPointerArgs {
158                    kind: fb::ThreadPointerKind::External,
159                    id: None,
160                    coord: None,
161                    uri: Some(uri),
162                    relay: None,
163                    has_kind_num: false,
164                    kind_num: 0,
165                },
166            )
167        }
168    }
169}
170
171fn encode_id<'bldr>(
172    builder: &mut FlatBufferBuilder<'bldr>,
173    id: &str,
174) -> WIPOffset<fb::BlockEventId<'bldr>> {
175    let id = builder.create_string(id);
176    fb::BlockEventId::create(builder, &fb::BlockEventIdArgs { id: Some(id) })
177}