streamson_lib/lib.rs
1#![crate_name = "streamson_lib"]
2
3//! This library is able to process large JSON data.
4//!
5//! It can have various matchers which matches the path (see [matcher](matcher/index.html))
6//!
7//! And various handlers to do something with found data (see [handlers](handler/index.html))
8//!
9//! # Examples
10//! ```
11//! use streamson_lib::{handler::{self, Handler}, matcher, strategy::{self, Strategy}};
12//! use std::{io, fs, sync::{Arc, Mutex}};
13//!
14//! let stdout_handler = Arc::new(Mutex::new(handler::Output::new(io::stdout())));
15//!
16//! let file = fs::File::create("out.txt").unwrap();
17//! let handler = handler::Group::new()
18//! .add_handler(Arc::new(Mutex::new(handler::Output::new(file))))
19//! .add_handler(stdout_handler.clone());
20//!
21//! let first_matcher = matcher::Simple::new(r#"{"users"}[]"#).unwrap();
22//! let second_matcher = matcher::Simple::new(r#"{"groups"}[]"#).unwrap();
23//!
24//! let mut trigger = strategy::Trigger::new();
25//!
26//! // exports users to stdout and out.txt
27//! trigger.add_matcher(
28//! Box::new(first_matcher),
29//! Arc::new(Mutex::new(handler.clone())),
30//! );
31//!
32//! // groups are going to be expoted only to stdout
33//! trigger.add_matcher(
34//! Box::new(second_matcher),
35//! stdout_handler,
36//! );
37//!
38//! for input in vec![
39//! br#"{"users": [1,2]"#.to_vec(),
40//! br#", "groups": [3, 4]}"#.to_vec(),
41//! ] {
42//! trigger.process(&input).unwrap();
43//! }
44//! ```
45//!
46//! ```
47//! use streamson_lib::{handler::{self, Handler}, matcher, strategy::{Strategy, self}};
48//! use std::{fs, io, sync::{Arc, Mutex}};
49//!
50//! let file = fs::File::create("out.txt").unwrap();
51//! let file_handler = Arc::new(
52//! Mutex::new(handler::Output::new(file))
53//! );
54//! let stdout_handler = Arc::new(Mutex::new(handler::Output::new(io::stdout())));
55//! let handler = handler::Group::new()
56//! .add_handler(stdout_handler)
57//! .add_handler(file_handler);
58//!
59//! let first_matcher = matcher::Depth::new(1, Some(2));
60//! let second_matcher = matcher::Simple::new(r#"{"users"}[]"#).unwrap();
61//! let matcher = matcher::Combinator::new(first_matcher) |
62//! matcher::Combinator::new(second_matcher);
63//!
64//! let mut trigger = strategy::Trigger::new();
65//!
66//! // Paths with depths 1, 2 are exported to out.txt
67//! trigger.add_matcher(
68//! Box::new(matcher),
69//! Arc::new(Mutex::new(handler)),
70//! );
71//!
72//! for input in vec![
73//! br#"{"users": [1,2]"#.to_vec(),
74//! br#", "groups": [3, 4]}"#.to_vec(),
75//! ] {
76//! trigger.process(&input).unwrap();
77//! }
78//! ```
79//!
80//! ```
81//! use streamson_lib::{handler::{self, Handler}, matcher, strategy::{Strategy, self}};
82//! use std::{io, fs, sync::{Arc, Mutex}};
83//!
84//! let file = fs::File::create("out.txt").unwrap();
85//! let file_handler = Arc::new(
86//! Mutex::new(handler::Output::new(file))
87//! );
88//! let stdout_handler = Arc::new(Mutex::new(handler::Output::new(io::stdout())));
89//! let handler = handler::Group::new()
90//! .add_handler(stdout_handler)
91//! .add_handler(file_handler);
92//!
93//! let matcher = matcher::Depth::new(1, Some(2));
94//!
95//! let mut trigger = strategy::Trigger::new();
96//!
97//! // Paths with depths 1, 2 are exported to out.txt
98//! trigger.add_matcher(
99//! Box::new(matcher),
100//! Arc::new(Mutex::new(handler)),
101//! );
102//!
103//! for input in vec![
104//! br#"{"users": [1,2]"#.to_vec(),
105//! br#", "groups": [3, 4]}"#.to_vec(),
106//! ] {
107//! trigger.process(&input).unwrap();
108//! }
109//! ```
110
111pub mod error;
112pub mod handler;
113pub mod matcher;
114pub mod path;
115pub mod strategy;
116pub mod streamer;
117
118pub use handler::Handler;
119pub use path::Path;
120pub use streamer::{Streamer, Token};
121
122#[cfg(doctest)]
123mod test_readme {
124 macro_rules! external_doc_test {
125 ($x:expr) => {
126 #[doc = $x]
127 extern "C" {}
128 };
129 }
130 external_doc_test!(include_str!("../README.md"));
131}
132
133#[cfg(test)]
134pub mod test {
135 pub trait Splitter {
136 fn split(&self, input: Vec<u8>) -> Vec<Vec<Vec<u8>>>;
137 }
138
139 pub(crate) struct Single;
140
141 impl Single {
142 pub fn new() -> Self {
143 Self
144 }
145 }
146
147 impl Splitter for Single {
148 fn split(&self, input: Vec<u8>) -> Vec<Vec<Vec<u8>>> {
149 vec![input.iter().map(|e| vec![*e]).collect()]
150 }
151 }
152
153 pub(crate) struct Window {
154 size: usize,
155 }
156
157 impl Window {
158 pub fn new(size: usize) -> Self {
159 Self { size }
160 }
161 }
162
163 impl Splitter for Window {
164 fn split(&self, input: Vec<u8>) -> Vec<Vec<Vec<u8>>> {
165 if input.len() <= self.size {
166 return vec![vec![input]];
167 }
168 let out_count = input.len() - self.size;
169 let mut res = vec![];
170 for i in 0..=out_count {
171 res.push(vec![
172 input[0..i].to_vec(),
173 input[i..self.size + i].to_vec(),
174 input[self.size + i..input.len()].to_vec(),
175 ]);
176 }
177 res
178 }
179 }
180}