Skip to main content

interstice_abi/schema/
query.rs

1use serde::{Deserialize, Serialize};
2
3use crate::{FieldDef, IntersticeType};
4use super::reducer::ReducerTableRef;
5
6/// Declared read access for a query (same [`ReducerTableRef`] rules as reducer `reads`).
7#[derive(Debug, Clone, Deserialize, Serialize)]
8pub struct QuerySchema {
9    pub name: String,
10    pub arguments: Vec<FieldDef>,
11    pub return_type: IntersticeType,
12    #[serde(default)]
13    pub reads: Vec<ReducerTableRef>,
14}
15
16impl QuerySchema {
17    pub fn new(
18        name: impl Into<String>,
19        arguments: Vec<FieldDef>,
20        return_type: IntersticeType,
21    ) -> Self {
22        Self::with_reads(name, arguments, return_type, Vec::new())
23    }
24
25    pub fn with_reads(
26        name: impl Into<String>,
27        arguments: Vec<FieldDef>,
28        return_type: IntersticeType,
29        reads: Vec<ReducerTableRef>,
30    ) -> Self {
31        Self {
32            name: name.into(),
33            arguments,
34            return_type,
35            reads,
36        }
37    }
38}
39
40#[cfg(test)]
41mod tests {
42    use super::QuerySchema;
43    use crate::{IntersticeType, ModuleSelection, NodeSelection, ReducerTableRef, decode, encode};
44
45    #[test]
46    fn query_schema_round_trip_includes_reads() {
47        let schema = QuerySchema::with_reads(
48            "total_committed",
49            vec![],
50            IntersticeType::U64,
51            vec![ReducerTableRef {
52                node_selection: NodeSelection::Current,
53                module_selection: ModuleSelection::Current,
54                table_name: "benchprogress".into(),
55            }],
56        );
57        let bytes = encode(&schema).expect("encode");
58        let decoded: QuerySchema = decode(&bytes).expect("decode");
59        assert_eq!(decoded.name, "total_committed");
60        assert_eq!(decoded.reads.len(), 1);
61        assert_eq!(decoded.reads[0].table_name, "benchprogress");
62    }
63
64    #[test]
65    fn query_schema_new_has_empty_reads() {
66        let s = QuerySchema::new("health", vec![], IntersticeType::Void);
67        assert!(s.reads.is_empty());
68    }
69}