Skip to main content

gateway_internal/
path_template.rs

1/// Represents a parsed HTTP path template.
2#[derive(Debug, Clone, PartialEq)]
3pub struct PathTemplate {
4    pub segments: Vec<Segment>,
5    pub verb: Option<String>,
6    pub template: String,
7}
8
9#[derive(Debug, Clone, PartialEq)]
10pub enum Segment {
11    Literal(String),
12    Wildcard,
13    DeepWildcard,
14    Variable(Variable),
15}
16
17#[derive(Debug, Clone, PartialEq)]
18pub struct Variable {
19    pub field_path: String,
20    pub segments: Vec<Segment>,
21}
22
23/// Operation codes for the compiled pattern match machine.
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25pub enum OpCode {
26    Nop = 0,
27    Push = 1,
28    LitPush = 2,
29    PushM = 3,
30    ConcatN = 4,
31    Capture = 5,
32}
33
34/// A compiled pattern used for matching paths.
35#[derive(Debug, Clone, PartialEq)]
36pub struct Pattern {
37    pub ops: Vec<Op>,
38    pub pool: Vec<String>,
39    pub vars: Vec<String>,
40    pub stack_size: usize,
41    pub tail_len: usize,
42    pub verb: Option<String>,
43}
44
45#[derive(Debug, Clone, PartialEq)]
46pub struct Op {
47    pub code: OpCode,
48    pub operand: i32,
49}
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54
55    #[test]
56    fn test_path_template_creation() {
57        let tmpl = PathTemplate {
58            segments: vec![
59                Segment::Literal("v1".to_string()),
60                Segment::Variable(Variable {
61                    field_path: "name".to_string(),
62                    segments: vec![Segment::Wildcard],
63                }),
64            ],
65            verb: None,
66            template: "/v1/{name=*}".to_string(),
67        };
68
69        assert_eq!(tmpl.segments.len(), 2);
70        match &tmpl.segments[0] {
71            Segment::Literal(l) => assert_eq!(l, "v1"),
72            _ => panic!("Expected Literal"),
73        }
74    }
75}