usage/
00_usage.rs

1use std::convert::TryFrom;
2use std::hash::{Hash, Hasher};
3use std::cmp::{Ord, Ordering, Eq};
4
5
6use std::fs::remove_dir_all;
7
8use serde::{Serialize, Deserialize};
9
10use json_surf::prelude::*;
11
12
13// Main struct
14#[derive(Serialize, Debug, Deserialize, PartialEq, PartialOrd, Clone)]
15struct UserInfo {
16    first: String,
17    last: String,
18    age: u8,
19}
20
21impl UserInfo {
22    pub fn new(first: String, last: String, age: u8) -> Self {
23        Self {
24            first,
25            last,
26            age,
27        }
28    }
29}
30
31impl Default for UserInfo {
32    fn default() -> Self {
33        let first = "".to_string();
34        let last = "".to_string();
35        let age = 0u8;
36        UserInfo::new(first, last, age)
37    }
38}
39
40fn main() {
41    // Specify home location for indexes
42    let home = ".store".to_string();
43    // Specify index name
44    let index_name = "usage".to_string();
45
46    // Prepare builder
47    let mut builder = SurferBuilder::default();
48    builder.set_home(&home);
49
50    let data = UserInfo::default();
51    builder.add_struct(index_name.clone(), &data);
52
53    // Prepare Surf
54    let mut surf = Surf::try_from(builder).unwrap();
55
56    // Prepare data to insert & search
57
58    // User 1: John Doe
59    let first = "John".to_string();
60    let last = "Doe".to_string();
61    let age = 20u8;
62    let john_doe = UserInfo::new(first, last, age);
63
64    // User 2: Jane Doe
65    let first = "Jane".to_string();
66    let last = "Doe".to_string();
67    let age = 18u8;
68    let jane_doe = UserInfo::new(first, last, age);
69
70    // See examples for more options
71    let users = vec![john_doe.clone(), jane_doe.clone()];
72    let _ = surf.insert(&index_name, &users).unwrap();
73
74    block_thread(1);
75
76    // See examples for more options
77    // Similar to SELECT * FROM users WHERE (age = 20 AND last = "Doe") OR (first = "Jane")
78    let conditions = vec![
79        OrCondition::new(
80            // (age = 20 AND last = "Doe")
81            vec![
82                AndCondition::new("age".to_string(), "20".to_string()),
83                AndCondition::new("last".to_string(), "doe".to_string())
84            ]),
85        OrCondition::new(
86            // (first = "Jane")
87            vec![
88                AndCondition::new("first".to_string(), "jane".to_string())
89            ])
90    ];
91
92    // Validate John and Jane Doe
93    let mut computed = surf.select::<UserInfo>(&index_name, &conditions).unwrap().unwrap();
94    let mut expected = vec![john_doe.clone(), jane_doe.clone(), ];
95    expected.sort();
96    computed.sort();
97    assert_eq!(expected, computed);
98
99    // Validated John's record - Alternate shortcut for query using one field only
100    let computed = surf.read_all_structs_by_field(&index_name, "age", "20");
101    let computed: Vec<UserInfo> = computed.unwrap().unwrap();
102    assert_eq!(vec![john_doe], computed);
103
104    // Delete John's record
105    let result = surf.delete(&index_name, "age", "20");
106    assert!(result.is_ok());
107
108    // John's was removed
109    let computed = surf.read_all_structs_by_field(&index_name, "age", "20");
110    let computed: Vec<UserInfo> = computed.unwrap().unwrap();
111    assert!(computed.is_empty());
112
113
114    // Clean-up
115    let path = surf.which_index(&index_name).unwrap();
116    let _ = remove_dir_all(&path);
117    let _ = remove_dir_all(&home);
118}
119
120/// Ignore all of this
121/// Convenience method for sorting & likely not required in user code
122impl Ord for UserInfo {
123    fn cmp(&self, other: &Self) -> Ordering {
124        if self.first == other.first && self.last == other.last {
125            return Ordering::Equal;
126        };
127        if self.first == other.first {
128            if self.last > other.last {
129                Ordering::Greater
130            } else {
131                Ordering::Less
132            }
133        } else {
134            if self.first > other.first {
135                Ordering::Greater
136            } else {
137                Ordering::Less
138            }
139        }
140    }
141}
142
143/// Ignore all of this
144/// Convenience method for sorting & likely not required in user code
145impl Eq for UserInfo {}
146
147/// Ignore all of this
148/// Convenience method for sorting & likely not required in user code
149impl Hash for UserInfo {
150    fn hash<H: Hasher>(&self, state: &mut H) {
151        for i in self.first.as_bytes() {
152            state.write_u8(*i);
153        }
154        for i in self.last.as_bytes() {
155            state.write_u8(*i);
156        }
157        state.write_u8(self.age);
158        state.finish();
159    }
160}