ents/
query_edge.rs

1use crate::{DatabaseError, Id};
2
3/// Sort order for edge queries
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum SortOrder {
6    /// Ascending order (smallest to largest)
7    Asc,
8    /// Descending order (largest to smallest)
9    Desc,
10}
11
12/// Cursor for pagination combining sort key and destination
13#[derive(Debug, Clone, PartialEq, Eq)]
14pub struct EdgeCursor<'a> {
15    /// The sort key value at the cursor position
16    pub sort_key: &'a [u8],
17    /// The destination ID at the cursor position
18    pub destination: Id,
19}
20
21impl<'a> EdgeCursor<'a> {
22    /// Create a new cursor
23    pub fn new(sort_key: &'a [u8], destination: Id) -> Self {
24        Self {
25            sort_key,
26            destination,
27        }
28    }
29}
30
31/// Edge result containing all three properties
32#[derive(Debug, Clone, PartialEq, Eq)]
33pub struct Edge {
34    /// Source entity ID
35    pub source: Id,
36    /// Sort key for ordering
37    pub sort_key: Vec<u8>,
38    /// Destination entity ID
39    pub dest: Id,
40}
41
42impl Edge {
43    /// Create a new edge
44    pub fn new(source: Id, sort_key: Vec<u8>, dest: Id) -> Self {
45        Self {
46            source,
47            sort_key,
48            dest,
49        }
50    }
51}
52
53/// Query parameters for edge enumeration
54#[derive(Debug, Clone)]
55pub struct EdgeQuery<'a> {
56    /// Filter edges by name (IN clause). If empty, no name filtering is applied.
57    pub edge_names: &'a [&'a [u8]],
58    /// Sort order for results
59    pub order: SortOrder,
60    /// Cursor for pagination:
61    /// - For Asc order: returns edges with (sort_key, destination) > cursor
62    /// - For Desc order: returns edges with (sort_key, destination) < cursor
63    pub cursor: Option<EdgeCursor<'a>>,
64}
65
66impl<'a> EdgeQuery<'a> {
67    /// Create a new query with ascending order
68    pub fn asc(edge_names: &'a [&'a [u8]]) -> Self {
69        Self {
70            edge_names,
71            order: SortOrder::Asc,
72            cursor: None,
73        }
74    }
75
76    /// Create a new query with descending order
77    pub fn desc(edge_names: &'a [&'a [u8]]) -> Self {
78        Self {
79            edge_names,
80            order: SortOrder::Desc,
81            cursor: None,
82        }
83    }
84
85    /// Set the pagination cursor
86    pub fn with_cursor(mut self, cursor: EdgeCursor<'a>) -> Self {
87        self.cursor = Some(cursor);
88        self
89    }
90
91    pub fn with_cursor_opt(mut self, cursor: Option<EdgeCursor<'a>>) -> Self {
92        self.cursor = cursor;
93        self
94    }
95}
96
97pub trait QueryEdge {
98    /// Find edges with flexible filtering and ordering options.
99    ///
100    /// # Arguments
101    /// * `source` - The source entity ID
102    /// * `query` - Query parameters specifying filters, ordering, and pagination
103    ///
104    /// Returns up to 100 edges matching the query criteria, sorted by (sort_key, destination).
105    /// For ascending order, edges are returned where (sort_key, destination) > cursor.
106    /// For descending order, edges are returned where (sort_key, destination) < cursor.
107    fn find_edges(
108        &self,
109        source: Id,
110        query: EdgeQuery,
111    ) -> Result<Vec<Edge>, DatabaseError>;
112}