Skip to main content

flp_gsp/
lib.rs

1// This library implements GSP (General Search Parser)
2// Copyright (C) 2026  Hakukaze Shikano
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program.  If not, see <https://www.gnu.org/licenses/>.
16
17#![forbid(unsafe_code)]
18
19pub mod interpreter;
20mod parser;
21
22use std::str::FromStr;
23
24use parser::comparison::Comparison;
25use parser::relation::Relation;
26
27#[derive(Debug, thiserror::Error)]
28pub enum Error {
29    #[error("Parser error {0}")]
30    Parser(String),
31}
32
33#[derive(Debug)]
34pub enum Node {
35    And(Box<Expression>, Box<Expression>),
36    Or(Box<Expression>, Box<Expression>),
37    Not(Box<Expression>),
38    Equal(String, String),
39    EqualCI(String, String),
40    Greater(String, String),
41    Less(String, String),
42    Wildcard(String, String),
43    Regex(String, String),
44    Any(String, Vec<String>),
45    Null(String),
46}
47
48#[derive(Debug)]
49pub struct Expression {
50    pub node: Node,
51}
52
53impl From<Comparison> for Expression {
54    fn from(c: Comparison) -> Self {
55        match c {
56            Comparison::IsEqual(c) => Self {
57                node: Node::Equal(c.left.0, c.right.0),
58            },
59            Comparison::IsEqualCI(c) => Self {
60                node: Node::EqualCI(c.left.0, c.right.0),
61            },
62            Comparison::IsGreater(c) => Self {
63                node: Node::Greater(c.left.0, c.right.0),
64            },
65            Comparison::IsLess(c) => Self {
66                node: Node::Less(c.left.0, c.right.0),
67            },
68            Comparison::IsWildcard(c) => Self {
69                node: Node::Wildcard(c.left.0, c.right.0),
70            },
71            Comparison::IsRegex(c) => Self {
72                node: Node::Regex(c.left.0, c.right.0),
73            },
74            Comparison::IsAny(c) => Self {
75                node: Node::Any(c.left.0, c.right.0),
76            },
77            Comparison::IsNull(c) => Self {
78                node: Node::Null(c.0.0),
79            },
80        }
81    }
82}
83
84impl From<Box<Relation>> for Expression {
85    fn from(relation: Box<Relation>) -> Self {
86        match *relation {
87            Relation::C(c) => c.into(),
88            Relation::Rar { left, right } => Self {
89                node: Node::And(Box::new(left.into()), Box::new(right.into())),
90            },
91            Relation::Rac { left, right } => Self {
92                node: Node::And(Box::new(left.into()), Box::new(right.into())),
93            },
94            Relation::Car { left, right } => Self {
95                node: Node::And(Box::new(left.into()), Box::new(right.into())),
96            },
97            Relation::Cac { left, right } => Self {
98                node: Node::And(Box::new(left.into()), Box::new(right.into())),
99            },
100            Relation::Ror { left, right } => Self {
101                node: Node::Or(Box::new(left.into()), Box::new(right.into())),
102            },
103            Relation::Roc { left, right } => Self {
104                node: Node::Or(Box::new(left.into()), Box::new(right.into())),
105            },
106            Relation::Cor { left, right } => Self {
107                node: Node::Or(Box::new(left.into()), Box::new(right.into())),
108            },
109            Relation::Coc { left, right } => Self {
110                node: Node::Or(Box::new(left.into()), Box::new(right.into())),
111            },
112            Relation::NR(r) => Self {
113                node: Node::Not(Box::new(r.into())),
114            },
115            Relation::NC(c) => Self {
116                node: Node::Not(Box::new(c.into())),
117            },
118        }
119    }
120}
121
122impl FromStr for Expression {
123    type Err = Error;
124
125    fn from_str(s: &str) -> Result<Self, Self::Err> {
126        Ok(parser::relation::relation(s)
127            .map_err(|err| Error::Parser(err.to_string()))?
128            .1
129            .into())
130    }
131}