, Error> {
20 | let mut res = Vec::new();
21 | let bts = std::fs::read(p)?;
22 | if let Ok(ss) = String::from_utf8(bts) {
23 | for (i, l) in ss.lines().enumerate() {
24 | if re.is_match(l) {
25 | res.push(Record {
26 | line: i,
27 | tx: l.to_string(),
28 | });
29 | }
30 | }
31 | }
32 | Ok(res)
33 | }
34 |
35 | fn process_path(p: P, re: &Regex, ff: &FF, ef: &EF) -> Result<(), Error>
36 | where
37 | P: AsRef,
38 | FF: Fn(&Path, Vec),
39 | EF: Fn(Error),
40 | {
41 | let p = p.as_ref();
42 | let md = p.metadata()?;
43 | let ft = md.file_type();
44 | if ft.is_file() {
45 | let dt = process_file(p, re)?;
46 | ff(p, dt);
47 | }
48 |
49 | if ft.is_dir() {
50 | let dd = std::fs::read_dir(p)?;
51 | for d in dd {
52 | if let Err(e) = process_path(d?.path(), re, ff, ef) {
53 | ef(e);
54 | }
55 | }
56 | }
57 |
58 | Ok(())
59 | }
60 |
61 | fn main() {
62 | if let Err(e) = run() {
63 | println!("There was an error: {}", e);
64 | }
65 | }
66 |
67 | fn run() -> Result<(), Error> {
68 | let cp = clap_app!(
69 | pgrep =>
70 | (version : crate_version!())
71 | (about : "A Grep like program")
72 | (author : "Matt")
73 | (@arg pattern : +required "The regex pattern to search for")
74 | (@arg file : -f --file +takes_value "The file to test")
75 | )
76 | .get_matches();
77 |
78 | let re = Regex::new(cp.value_of("pattern").unwrap())?;
79 |
80 | let p = process_path(
81 | cp.value_of("file").ok_or(ArgErr { arg: "file" })?,
82 | &re,
83 | &|pt, v| {
84 | println!("{:?}", pt);
85 | println!("{:?}", v);
86 | },
87 | &|e| {
88 | println!("Error:{}", e);
89 | },
90 | );
91 |
92 | println!("{:?}", p);
93 | Ok(())
94 | }
95 |
--------------------------------------------------------------------------------
/pgrep/test_data/t1.txt:
--------------------------------------------------------------------------------
1 | help me I'm falling.
2 | Hello world
3 |
4 | Hello People of te world
5 |
6 | Lets all say Hello
7 |
--------------------------------------------------------------------------------
/pgrep/test_data/t2.txt:
--------------------------------------------------------------------------------
1 | I'm going for a walk
2 |
3 | I'm going to say Hello
4 |
5 | People will say Hello back
6 |
7 |
--------------------------------------------------------------------------------
/shop_base/Cargo.lock:
--------------------------------------------------------------------------------
1 | [[package]]
2 | name = "aho-corasick"
3 | version = "0.6.10"
4 | source = "registry+https://github.com/rust-lang/crates.io-index"
5 | dependencies = [
6 | "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
7 | ]
8 |
9 | [[package]]
10 | name = "ansi_term"
11 | version = "0.11.0"
12 | source = "registry+https://github.com/rust-lang/crates.io-index"
13 | dependencies = [
14 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
15 | ]
16 |
17 | [[package]]
18 | name = "atty"
19 | version = "0.2.11"
20 | source = "registry+https://github.com/rust-lang/crates.io-index"
21 | dependencies = [
22 | "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
23 | "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
24 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
25 | ]
26 |
27 | [[package]]
28 | name = "autocfg"
29 | version = "0.1.2"
30 | source = "registry+https://github.com/rust-lang/crates.io-index"
31 |
32 | [[package]]
33 | name = "backtrace"
34 | version = "0.3.14"
35 | source = "registry+https://github.com/rust-lang/crates.io-index"
36 | dependencies = [
37 | "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
38 | "backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
39 | "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
40 | "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
41 | "rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
42 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
43 | ]
44 |
45 | [[package]]
46 | name = "backtrace-sys"
47 | version = "0.1.28"
48 | source = "registry+https://github.com/rust-lang/crates.io-index"
49 | dependencies = [
50 | "cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
51 | "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
52 | ]
53 |
54 | [[package]]
55 | name = "bitflags"
56 | version = "1.0.4"
57 | source = "registry+https://github.com/rust-lang/crates.io-index"
58 |
59 | [[package]]
60 | name = "byteorder"
61 | version = "1.3.1"
62 | source = "registry+https://github.com/rust-lang/crates.io-index"
63 |
64 | [[package]]
65 | name = "cc"
66 | version = "1.0.31"
67 | source = "registry+https://github.com/rust-lang/crates.io-index"
68 |
69 | [[package]]
70 | name = "cfg-if"
71 | version = "0.1.7"
72 | source = "registry+https://github.com/rust-lang/crates.io-index"
73 |
74 | [[package]]
75 | name = "clap"
76 | version = "2.32.0"
77 | source = "registry+https://github.com/rust-lang/crates.io-index"
78 | dependencies = [
79 | "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
80 | "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
81 | "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
82 | "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
83 | "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
84 | "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
85 | "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
86 | ]
87 |
88 | [[package]]
89 | name = "diesel"
90 | version = "1.4.2"
91 | source = "registry+https://github.com/rust-lang/crates.io-index"
92 | dependencies = [
93 | "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
94 | "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
95 | "diesel_derives 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
96 | "pq-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
97 | ]
98 |
99 | [[package]]
100 | name = "diesel_derives"
101 | version = "1.4.0"
102 | source = "registry+https://github.com/rust-lang/crates.io-index"
103 | dependencies = [
104 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
105 | "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
106 | "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)",
107 | ]
108 |
109 | [[package]]
110 | name = "dotenv"
111 | version = "0.13.0"
112 | source = "registry+https://github.com/rust-lang/crates.io-index"
113 | dependencies = [
114 | "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
115 | "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
116 | "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
117 | ]
118 |
119 | [[package]]
120 | name = "failure"
121 | version = "0.1.5"
122 | source = "registry+https://github.com/rust-lang/crates.io-index"
123 | dependencies = [
124 | "backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
125 | "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
126 | ]
127 |
128 | [[package]]
129 | name = "failure_derive"
130 | version = "0.1.5"
131 | source = "registry+https://github.com/rust-lang/crates.io-index"
132 | dependencies = [
133 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
134 | "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
135 | "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)",
136 | "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
137 | ]
138 |
139 | [[package]]
140 | name = "lazy_static"
141 | version = "1.3.0"
142 | source = "registry+https://github.com/rust-lang/crates.io-index"
143 |
144 | [[package]]
145 | name = "libc"
146 | version = "0.2.50"
147 | source = "registry+https://github.com/rust-lang/crates.io-index"
148 |
149 | [[package]]
150 | name = "memchr"
151 | version = "2.2.0"
152 | source = "registry+https://github.com/rust-lang/crates.io-index"
153 |
154 | [[package]]
155 | name = "pq-sys"
156 | version = "0.4.6"
157 | source = "registry+https://github.com/rust-lang/crates.io-index"
158 | dependencies = [
159 | "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
160 | ]
161 |
162 | [[package]]
163 | name = "proc-macro2"
164 | version = "0.4.27"
165 | source = "registry+https://github.com/rust-lang/crates.io-index"
166 | dependencies = [
167 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
168 | ]
169 |
170 | [[package]]
171 | name = "quote"
172 | version = "0.6.11"
173 | source = "registry+https://github.com/rust-lang/crates.io-index"
174 | dependencies = [
175 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
176 | ]
177 |
178 | [[package]]
179 | name = "redox_syscall"
180 | version = "0.1.51"
181 | source = "registry+https://github.com/rust-lang/crates.io-index"
182 |
183 | [[package]]
184 | name = "redox_termios"
185 | version = "0.1.1"
186 | source = "registry+https://github.com/rust-lang/crates.io-index"
187 | dependencies = [
188 | "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
189 | ]
190 |
191 | [[package]]
192 | name = "regex"
193 | version = "1.1.2"
194 | source = "registry+https://github.com/rust-lang/crates.io-index"
195 | dependencies = [
196 | "aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
197 | "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
198 | "regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
199 | "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
200 | "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
201 | ]
202 |
203 | [[package]]
204 | name = "regex-syntax"
205 | version = "0.6.5"
206 | source = "registry+https://github.com/rust-lang/crates.io-index"
207 | dependencies = [
208 | "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
209 | ]
210 |
211 | [[package]]
212 | name = "rustc-demangle"
213 | version = "0.1.13"
214 | source = "registry+https://github.com/rust-lang/crates.io-index"
215 |
216 | [[package]]
217 | name = "serde"
218 | version = "1.0.90"
219 | source = "registry+https://github.com/rust-lang/crates.io-index"
220 |
221 | [[package]]
222 | name = "serde_derive"
223 | version = "1.0.90"
224 | source = "registry+https://github.com/rust-lang/crates.io-index"
225 | dependencies = [
226 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
227 | "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
228 | "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)",
229 | ]
230 |
231 | [[package]]
232 | name = "shop_base"
233 | version = "0.1.0"
234 | dependencies = [
235 | "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
236 | "diesel 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
237 | "dotenv 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
238 | "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
239 | "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
240 | "serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
241 | ]
242 |
243 | [[package]]
244 | name = "strsim"
245 | version = "0.7.0"
246 | source = "registry+https://github.com/rust-lang/crates.io-index"
247 |
248 | [[package]]
249 | name = "syn"
250 | version = "0.15.29"
251 | source = "registry+https://github.com/rust-lang/crates.io-index"
252 | dependencies = [
253 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
254 | "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
255 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
256 | ]
257 |
258 | [[package]]
259 | name = "synstructure"
260 | version = "0.10.1"
261 | source = "registry+https://github.com/rust-lang/crates.io-index"
262 | dependencies = [
263 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
264 | "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
265 | "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)",
266 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
267 | ]
268 |
269 | [[package]]
270 | name = "termion"
271 | version = "1.5.1"
272 | source = "registry+https://github.com/rust-lang/crates.io-index"
273 | dependencies = [
274 | "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
275 | "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
276 | "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
277 | ]
278 |
279 | [[package]]
280 | name = "textwrap"
281 | version = "0.10.0"
282 | source = "registry+https://github.com/rust-lang/crates.io-index"
283 | dependencies = [
284 | "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
285 | ]
286 |
287 | [[package]]
288 | name = "thread_local"
289 | version = "0.3.6"
290 | source = "registry+https://github.com/rust-lang/crates.io-index"
291 | dependencies = [
292 | "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
293 | ]
294 |
295 | [[package]]
296 | name = "ucd-util"
297 | version = "0.1.3"
298 | source = "registry+https://github.com/rust-lang/crates.io-index"
299 |
300 | [[package]]
301 | name = "unicode-width"
302 | version = "0.1.5"
303 | source = "registry+https://github.com/rust-lang/crates.io-index"
304 |
305 | [[package]]
306 | name = "unicode-xid"
307 | version = "0.1.0"
308 | source = "registry+https://github.com/rust-lang/crates.io-index"
309 |
310 | [[package]]
311 | name = "utf8-ranges"
312 | version = "1.0.2"
313 | source = "registry+https://github.com/rust-lang/crates.io-index"
314 |
315 | [[package]]
316 | name = "vcpkg"
317 | version = "0.2.6"
318 | source = "registry+https://github.com/rust-lang/crates.io-index"
319 |
320 | [[package]]
321 | name = "vec_map"
322 | version = "0.8.1"
323 | source = "registry+https://github.com/rust-lang/crates.io-index"
324 |
325 | [[package]]
326 | name = "winapi"
327 | version = "0.3.6"
328 | source = "registry+https://github.com/rust-lang/crates.io-index"
329 | dependencies = [
330 | "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
331 | "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
332 | ]
333 |
334 | [[package]]
335 | name = "winapi-i686-pc-windows-gnu"
336 | version = "0.4.0"
337 | source = "registry+https://github.com/rust-lang/crates.io-index"
338 |
339 | [[package]]
340 | name = "winapi-x86_64-pc-windows-gnu"
341 | version = "0.4.0"
342 | source = "registry+https://github.com/rust-lang/crates.io-index"
343 |
344 | [metadata]
345 | "checksum aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "81ce3d38065e618af2d7b77e10c5ad9a069859b4be3c2250f674af3840d9c8a5"
346 | "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
347 | "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
348 | "checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799"
349 | "checksum backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "cd5a90e2b463010cd0e0ce9a11d4a9d5d58d9f41d4a6ba3dcaf9e68b466e88b4"
350 | "checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6"
351 | "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
352 | "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
353 | "checksum cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "c9ce8bb087aacff865633f0bd5aeaed910fe2fe55b55f4739527f2e023a2e53d"
354 | "checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4"
355 | "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
356 | "checksum diesel 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8d24935ba50c4a8dc375a0fd1f8a2ba6bdbdc4125713126a74b965d6a01a06d7"
357 | "checksum diesel_derives 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "62a27666098617d52c487a41f70de23d44a1dc1f3aa5877ceba2790fb1f1cab4"
358 | "checksum dotenv 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d0a1279c96732bc6800ce6337b6a614697b0e74ae058dc03c62ebeb78b4d86"
359 | "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
360 | "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
361 | "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
362 | "checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1"
363 | "checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39"
364 | "checksum pq-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6ac25eee5a0582f45a67e837e350d784e7003bd29a5f460796772061ca49ffda"
365 | "checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915"
366 | "checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1"
367 | "checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85"
368 | "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
369 | "checksum regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53ee8cfdddb2e0291adfb9f13d31d3bbe0a03c9a402c01b1e24188d86c35b24f"
370 | "checksum regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8c2f35eedad5295fdf00a63d7d4b238135723f92b434ec06774dad15c7ab0861"
371 | "checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619"
372 | "checksum serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "aa5f7c20820475babd2c077c3ab5f8c77a31c15e16ea38687b4c02d3e48680f4"
373 | "checksum serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "58fc82bec244f168b23d1963b45c8bf5726e9a15a9d146a067f9081aeed2de79"
374 | "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
375 | "checksum syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1825685f977249735d510a242a6727b46efe914bb67e38d30c071b1b72b1d5c2"
376 | "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
377 | "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
378 | "checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
379 | "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
380 | "checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
381 | "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
382 | "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
383 | "checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737"
384 | "checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d"
385 | "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
386 | "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
387 | "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
388 | "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
389 |
--------------------------------------------------------------------------------
/shop_base/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "shop_base"
3 | version = "0.1.0"
4 | authors = ["matthew "]
5 | edition = "2018"
6 |
7 | [[bin]]
8 | name = "shop_cli"
9 | path = "src/cli.rs"
10 |
11 | [lib]
12 | name = "shop_base"
13 | path = "src/lib.rs"
14 |
15 | [dependencies]
16 |
17 | serde = "1.0.90"
18 | serde_derive = "1.0.90"
19 | diesel = {version = "1.4.1", features = ["postgres"]}
20 | dotenv = "0.13.0"
21 | failure = "0.1.5"
22 | clap = "2.32.0"
23 |
--------------------------------------------------------------------------------
/shop_base/diesel.toml:
--------------------------------------------------------------------------------
1 | # For documentation on how to configure this file,
2 | # see diesel.rs/guides/configuring-diesel-cli
3 |
4 | [print_schema]
5 | file = "src/schema.rs"
6 |
--------------------------------------------------------------------------------
/shop_base/migrations/00000000000000_diesel_initial_setup/down.sql:
--------------------------------------------------------------------------------
1 | -- This file was automatically created by Diesel to setup helper functions
2 | -- and other internal bookkeeping. This file is safe to edit, any future
3 | -- changes will be added to existing projects as new migrations.
4 |
5 | DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass);
6 | DROP FUNCTION IF EXISTS diesel_set_updated_at();
7 |
--------------------------------------------------------------------------------
/shop_base/migrations/00000000000000_diesel_initial_setup/up.sql:
--------------------------------------------------------------------------------
1 | -- This file was automatically created by Diesel to setup helper functions
2 | -- and other internal bookkeeping. This file is safe to edit, any future
3 | -- changes will be added to existing projects as new migrations.
4 |
5 |
6 |
7 |
8 | -- Sets up a trigger for the given table to automatically set a column called
9 | -- `updated_at` whenever the row is modified (unless `updated_at` was included
10 | -- in the modified columns)
11 | --
12 | -- # Example
13 | --
14 | -- ```sql
15 | -- CREATE TABLE users (id SERIAL PRIMARY KEY, updated_at TIMESTAMP NOT NULL DEFAULT NOW());
16 | --
17 | -- SELECT diesel_manage_updated_at('users');
18 | -- ```
19 | CREATE OR REPLACE FUNCTION diesel_manage_updated_at(_tbl regclass) RETURNS VOID AS $$
20 | BEGIN
21 | EXECUTE format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s
22 | FOR EACH ROW EXECUTE PROCEDURE diesel_set_updated_at()', _tbl);
23 | END;
24 | $$ LANGUAGE plpgsql;
25 |
26 | CREATE OR REPLACE FUNCTION diesel_set_updated_at() RETURNS trigger AS $$
27 | BEGIN
28 | IF (
29 | NEW IS DISTINCT FROM OLD AND
30 | NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at
31 | ) THEN
32 | NEW.updated_at := current_timestamp;
33 | END IF;
34 | RETURN NEW;
35 | END;
36 | $$ LANGUAGE plpgsql;
37 |
--------------------------------------------------------------------------------
/shop_base/migrations/2019-03-26-103937_create_items/down.sql:
--------------------------------------------------------------------------------
1 | -- This file should undo anything in `up.sql`
2 | DROP TABLE items
3 |
--------------------------------------------------------------------------------
/shop_base/migrations/2019-03-26-103937_create_items/up.sql:
--------------------------------------------------------------------------------
1 | -- Your SQL goes here
2 | CREATE TABLE items (
3 | id SERIAL PRIMARY KEY,
4 | name VARCHAR NOT NULL,
5 | description VARCHAR NOT NULL,
6 | price INTEGER NOT NULL,
7 | instock INTEGER NOT NULL DEFAULT 0
8 | )
9 |
--------------------------------------------------------------------------------
/shop_base/src/cli.rs:
--------------------------------------------------------------------------------
1 | extern crate shop_base;
2 | use clap::{clap_app, crate_version};
3 | use failure::Error;
4 | use shop_base::Conn;
5 |
6 | fn main() -> Result<(), Error> {
7 | let clap = clap_app!(blog_cli =>
8 | (about:"Edit the shop_base contents")
9 | (version : crate_version!())
10 | (author: "Matthew Stoodley")
11 | (@subcommand put =>
12 | (about : "Put an item on the database")
13 | (@arg name:+required "The name of the item")
14 | (@arg description:+required "A description of the item")
15 | (@arg price:+required "The price of the item in pence")
16 | )
17 | (@subcommand find =>
18 | (about : "Find items matching a given name part")
19 | (@arg name:+required "A partial match of the item name")
20 | (@arg limit:+takes_value "The maximum number of entries to return")
21 | )
22 | (@subcommand stock =>
23 | (about :"Set the stock level for an item in the store")
24 | (@arg id:+required "The Item id")
25 | (@arg amount:+required "The new value")
26 | (@arg rel:-r "Add to previous value")
27 | )
28 | )
29 | .get_matches();
30 |
31 | let conn = Conn::new()?;
32 | if let Some(sub) = clap.subcommand_matches("put") {
33 | let r = conn.put_item(
34 | sub.value_of("name").unwrap(),
35 | sub.value_of("description").unwrap(),
36 | sub.value_of("price").and_then(|v| v.parse().ok()).unwrap(),
37 | )?;
38 | println!("Added Item {:?}", r);
39 | }
40 |
41 | if let Some(sub) = clap.subcommand_matches("find") {
42 | let r = conn.find_items(
43 | sub.value_of("name").unwrap(),
44 | sub.value_of("limit")
45 | .and_then(|v| v.parse().ok())
46 | .unwrap_or(5),
47 | )?;
48 | for p in r {
49 | println!("\n----------Entry----------\n");
50 | println!("{:?}", p);
51 | }
52 | }
53 |
54 | if let Some(sub) = clap.subcommand_matches("stock") {
55 | let r = conn.set_stock(
56 | sub.value_of("id").unwrap().parse().unwrap(),
57 | sub.value_of("amount").unwrap().parse().unwrap(),
58 | sub.is_present("rel"),
59 | );
60 | println!("Updated : {:?}", r);
61 | }
62 | Ok(())
63 | }
64 |
--------------------------------------------------------------------------------
/shop_base/src/lib.rs:
--------------------------------------------------------------------------------
1 | #[macro_use]
2 | extern crate diesel;
3 | use diesel::pg::PgConnection;
4 | use diesel::prelude::*;
5 | use failure::Error;
6 |
7 | mod models;
8 | pub use models::{Item, NewItem};
9 | mod schema;
10 | use schema::items;
11 |
12 | pub struct Conn(PgConnection);
13 |
14 | impl Conn {
15 | pub fn new() -> Result {
16 | dotenv::dotenv().ok();
17 | let db_url = std::env::var("DATABASE_URL")?;
18 | Ok(Conn(PgConnection::establish(&db_url)?))
19 | }
20 |
21 | pub fn put_item(&self, name: &str, description: &str, price: i32) -> Result- {
22 | let nit = NewItem {
23 | name,
24 | description,
25 | price,
26 | };
27 | diesel::insert_into(items::table)
28 | .values(&nit)
29 | .get_result(&self.0)
30 | .map_err(|x| x.into())
31 | }
32 |
33 | pub fn find_items(&self, name: &str, lim: i64) -> Result, Error> {
34 | let lname = format!("%{}%", name);
35 | items::table
36 | .filter(items::name.ilike(lname))
37 | .order(items::id.desc())
38 | .limit(lim)
39 | .load(&self.0)
40 | .map_err(|e| e.into())
41 | }
42 |
43 | pub fn set_stock(&self, id: i32, mut n: i32, rel: bool) -> Result
- {
44 | if rel {
45 | let items: Vec
- = items::table.find(id).for_update().load(&self.0)?;
46 | n += items[0].instock;
47 | }
48 | diesel::update(items::table::find(items::table, id))
49 | .set(items::instock.eq(n))
50 | .get_result(&self.0)
51 | .map_err(|e| e.into())
52 | }
53 | }
54 |
55 | #[cfg(test)]
56 | mod tests {
57 | #[test]
58 | fn it_works() {
59 | assert_eq!(2 + 2, 4);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/shop_base/src/models.rs:
--------------------------------------------------------------------------------
1 | use crate::schema::items;
2 | use serde_derive::*;
3 |
4 | #[derive(Queryable, Serialize, Deserialize, Clone, Debug)]
5 | pub struct Item {
6 | pub id: i32,
7 | pub name: String,
8 | pub description: String,
9 | pub price: i32,
10 | pub instock: i32,
11 | }
12 |
13 | #[derive(Queryable, Insertable, Clone, Debug)]
14 | #[table_name = "items"]
15 | pub struct NewItem<'a> {
16 | pub name: &'a str,
17 | pub description: &'a str,
18 | pub price: i32,
19 | }
20 |
--------------------------------------------------------------------------------
/shop_base/src/schema.rs:
--------------------------------------------------------------------------------
1 | table! {
2 | items (id) {
3 | id -> Int4,
4 | name -> Varchar,
5 | description -> Varchar,
6 | price -> Int4,
7 | instock -> Int4,
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/shop_site/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "shop_site"
3 | version = "0.1.0"
4 | authors = ["matthew "]
5 | edition = "2018"
6 |
7 | [dependencies]
8 | actix = "0.7.9"
9 | actix-web = "0.7.19"
10 | failure = "0.1.5"
11 | shop_base = {path = "../shop_base"}
12 | futures = "0.1.26"
13 | serde = "1.0.90"
14 | serde_derive = "1.0.90"
15 | lazy_static = "1.3.0"
16 | handlebars = "1.1.0"
17 |
--------------------------------------------------------------------------------
/shop_site/src/main.rs:
--------------------------------------------------------------------------------
1 | use actix::prelude::*;
2 | use actix_web::middleware::session::{CookieSessionBackend, RequestSession, SessionStorage};
3 | use actix_web::{
4 | fs, http, server::HttpServer, App, AsyncResponder, Form, HttpRequest, HttpResponse, Query,
5 | Responder, State,
6 | };
7 | use failure::Error;
8 | use futures::Future;
9 | use handlebars::Handlebars;
10 | use serde_derive::*;
11 | use shop_base::{Conn, Item};
12 |
13 | enum DBRequest {
14 | FindItems(String, i64),
15 | }
16 | enum DBResponse {
17 | FoundItems(Vec
- ),
18 | }
19 |
20 | impl Message for DBRequest {
21 | type Result = Result;
22 | }
23 |
24 | pub struct DBExecutor {
25 | conn: Conn,
26 | }
27 |
28 | impl Actor for DBExecutor {
29 | type Context = SyncContext;
30 | }
31 |
32 | impl Handler for DBExecutor {
33 | type Result = Result;
34 | fn handle(&mut self, msg: DBRequest, _: &mut Self::Context) -> Self::Result {
35 | match msg {
36 | DBRequest::FindItems(s, i) => Ok(DBResponse::FoundItems(self.conn.find_items(&s, i)?)),
37 | }
38 | }
39 | }
40 |
41 | #[derive(Deserialize, Debug)]
42 | struct FormFindItems {
43 | search_term: String,
44 | limit: Option,
45 | }
46 |
47 | fn search(
48 | page_hand: &Addr,
49 | ffi: &FormFindItems,
50 | req: &HttpRequest,
51 | ) -> impl Responder {
52 | let searches = req
53 | .session()
54 | .get::("searches")
55 | .expect("Session Should exist")
56 | .unwrap_or(0)
57 | + 1;
58 | req.session()
59 | .set("searches", searches)
60 | .expect("Could not set searches");
61 | page_hand
62 | .send(DBRequest::FindItems(
63 | ffi.search_term.clone(),
64 | ffi.limit.unwrap_or(5),
65 | ))
66 | .and_then(move |r| match r {
67 | Ok(DBResponse::FoundItems(v)) => Ok(HttpResponse::Ok()
68 | .content_type("text/html")
69 | .body(TEMPLATES.render("item_list", &(&v, searches)).unwrap())),
70 | Err(_) => Ok(HttpResponse::Ok().json("Error finding Database")),
71 | })
72 | .responder()
73 | }
74 |
75 | lazy_static::lazy_static! {
76 | static ref TEMPLATES:Handlebars = {
77 | let mut res = Handlebars::new();
78 | let df = std::fs::read_to_string("test_site/templates/item_list.html").expect("Could not read template");
79 | res.register_template_string("item_list",df).expect("Could not parse template");
80 | res
81 | };
82 | }
83 |
84 | fn main() {
85 | let sys = System::new("shop_site");
86 |
87 | let db_hand = SyncArbiter::start(3, || DBExecutor {
88 | conn: Conn::new().unwrap(),
89 | });
90 |
91 | HttpServer::new(move || {
92 | vec![
93 | App::with_state(db_hand.clone())
94 | .prefix("/db/")
95 | .middleware(SessionStorage::new(
96 | CookieSessionBackend::signed(&[0; 32]).secure(false),
97 | ))
98 | .resource("/", |r| {
99 | r.f(|_| {
100 | HttpResponse::Ok()
101 | .content_type("text/plain")
102 | .body("This is the Database side of the app")
103 | })
104 | })
105 | .resource("/find_items", |r| {
106 | r.method(http::Method::GET).with(
107 | |(state, query, req): (
108 | State>,
109 | Query,
110 | HttpRequest<_>,
111 | )| { search(&state, &query, &req) },
112 | );
113 |
114 | r.method(http::Method::POST).with(
115 | |(state, form, req): (
116 | State>,
117 | Form,
118 | HttpRequest<_>,
119 | )| { search(&state, &form, &req) },
120 | )
121 | })
122 | .boxed(),
123 | App::new()
124 | .handler(
125 | "/",
126 | fs::StaticFiles::new("test_site/static/")
127 | .unwrap()
128 | .show_files_listing()
129 | .index_file("index.html"),
130 | )
131 | .boxed(),
132 | ]
133 | })
134 | .bind("127.0.0.1:8088")
135 | .unwrap()
136 | .start();
137 |
138 | sys.run();
139 |
140 | println!("Done");
141 | }
142 |
--------------------------------------------------------------------------------
/shop_site/test_site/static/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
Welcome to the Shop
8 | I hope you like it here
9 | Get Request
10 |
15 | Post Request
16 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/shop_site/test_site/templates/item_list.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Welcome to the Shop
8 | I hope you like it here
9 | Get Request
10 |
15 | Post Request
16 |
21 |
22 | Searches so far = {{this.1}}
23 | Results
24 | {{#each this.0}}
25 |
26 | {{id}} : {{name}}
27 |
28 | {{/each}}
29 |
30 |
31 |
--------------------------------------------------------------------------------