arde/
library.rs

1//! Standard modules (storages) for niceties
2//! like being able to check if 2 different variables are actually the same value
3
4use crate::{atom, FixedStorage, GroundedTerm, Storage};
5
6pub struct StandardLibrary;
7
8impl Storage for StandardLibrary {
9    fn _query(&self, name: &crate::parser::Predicate, terms: &[&GroundedTerm]) -> bool {
10        if &name.to_string() == "@is" {
11            if terms.len() != 2 {
12                return false;
13            }
14            terms[0] == terms[1]
15        } else if &name.to_string() == "@exrange" {
16            if terms.len() != 3 {
17                return false;
18            }
19            let value = match terms[0] {
20                GroundedTerm::Integer(i) => i,
21                _ => return false,
22            };
23            match terms[1] {
24                GroundedTerm::Integer(i) => match terms[2] {
25                    GroundedTerm::Integer(j) => i <= value && j > value,
26                    _ => false,
27                },
28                _ => false,
29            }
30        } else if &name.to_string() == "@incrange" {
31            if terms.len() != 3 {
32                return false;
33            }
34            let value = match terms[0] {
35                GroundedTerm::Integer(i) => i,
36                _ => return false,
37            };
38            match terms[1] {
39                GroundedTerm::Integer(i) => match terms[2] {
40                    GroundedTerm::Integer(j) => i <= value && j >= value,
41                    _ => false,
42                },
43                _ => false,
44            }
45        } else if &name.to_string() == "@type" {
46            if terms.len() != 2 {
47                return false;
48            }
49            match terms[0] {
50                GroundedTerm::Integer(_) => terms[1] == &GroundedTerm::String("integer".into()),
51                GroundedTerm::String(_) => terms[1] == &GroundedTerm::String("string".into()),
52                GroundedTerm::Uuid(_) => terms[1] == &GroundedTerm::String("uuid".into()),
53                GroundedTerm::Boolean(_) => terms[1] == &GroundedTerm::String("boolean".into()),
54            }
55        } else if &name.to_string() == "@version_check" {
56            if terms.len() != 1 {
57                return false;
58            }
59            match terms[0] {
60                GroundedTerm::String(s) => s == "0.0.1",
61                GroundedTerm::Integer(i) => *i == 0,
62                _ => false,
63            }
64        } else {
65            false
66        }
67    }
68
69    fn can_query(&self, name: &crate::parser::Predicate, arity: usize) -> bool {
70        type QueryDefinition<'a> = (&'a str, fn(usize) -> bool);
71        const HANDLED_QUERIES: &[QueryDefinition] = &[
72            ("@is", |arity| arity == 2),
73            ("@exrange", |arity| arity == 3),
74            ("@incrange", |arity| arity == 3),
75            ("@type", |arity| arity == 2),
76            ("@version_check", |arity| arity == 1),
77        ];
78
79        HANDLED_QUERIES
80            .iter()
81            .filter(|(fc, _)| fc == &name.to_string())
82            .any(|(_, f)| f(arity))
83    }
84
85    fn as_fixed(&self) -> Option<&dyn crate::FixedStorage> {
86        Some(self)
87    }
88}
89
90impl FixedStorage for StandardLibrary {
91    fn get_facts(&self) -> std::collections::HashSet<crate::GroundedAtom> {
92        vec![
93            atom!(@stdlib_version (string "0.0.1".into())),
94            atom!(@stdlib_version (integer 0)),
95            atom!(@stdlib_version_prerelease (boolean true)),
96        ]
97        .into_iter()
98        .collect()
99    }
100}