rust_store_core/pipeline/
token.rs1use serde_json::{Map, Value};
4
5#[derive(Debug, Clone, PartialEq)]
6pub struct Token {
7 pub kind: &'static str,
8 pub value: String,
9}
10
11fn is_ident_start(c: char) -> bool {
12 c.is_ascii_alphabetic() || c == '_' || c == '$'
13}
14
15fn is_ident_char(c: char) -> bool {
16 c.is_ascii_alphanumeric() || c == '_' || c == '$' || c == '.'
17}
18
19fn is_ref_char(c: char) -> bool {
20 c.is_ascii_alphanumeric() || c == '_'
21}
22
23pub fn tokenize(gql: &str) -> Vec<Token> {
24 let chars: Vec<char> = gql.chars().collect();
25 let n = chars.len();
26 let mut tokens = Vec::new();
27 let mut i = 0;
28 while i < n {
29 let ch = chars[i];
30 if ch.is_whitespace() {
32 i += 1;
33 continue;
34 }
35 if "(){},:".contains(ch) {
37 tokens.push(Token {
38 kind: "p",
39 value: ch.to_string(),
40 });
41 i += 1;
42 continue;
43 }
44 if is_ident_start(ch) {
46 let mut v = String::new();
47 while i < n && is_ident_char(chars[i]) {
48 v.push(chars[i]);
49 i += 1;
50 }
51 tokens.push(Token {
52 kind: "id",
53 value: v,
54 });
55 continue;
56 }
57 if ch == '@' {
59 let mut v = String::from("@");
60 i += 1;
61 while i < n && is_ref_char(chars[i]) {
62 v.push(chars[i]);
63 i += 1;
64 }
65 tokens.push(Token {
66 kind: "ref",
67 value: v,
68 });
69 continue;
70 }
71 i += 1; }
73 tokens
74}
75
76pub fn token_to_value(t: &Token) -> Value {
77 Value::Object(Map::from_iter([
78 ("t".to_string(), Value::String(t.kind.to_string())),
79 ("v".to_string(), Value::String(t.value.clone())),
80 ]))
81}