streamson_lib/handler/
shorten.rs1use super::Handler;
29use crate::{error, path::Path, streamer::Token};
30use std::{any::Any, str::FromStr};
31
32#[derive(Debug)]
35pub struct Shorten {
36 max_length: usize,
38
39 used: usize,
41
42 terminator: String,
45}
46
47impl Shorten {
48 pub fn new(max_length: usize, terminator: String) -> Self {
50 Self {
51 max_length,
52 terminator,
53 used: 0,
54 }
55 }
56}
57
58impl FromStr for Shorten {
59 type Err = error::Handler;
60 fn from_str(input: &str) -> Result<Self, Self::Err> {
61 let splitted: Vec<_> = input.split(',').collect();
62 if splitted.len() == 2 {
63 Ok(Self::new(
64 splitted[0].parse().map_err(error::Handler::new)?,
65 splitted[1].to_string(),
66 ))
67 } else {
68 Err(error::Handler::new("Failed to parse"))
69 }
70 }
71}
72
73impl Handler for Shorten {
74 fn start(
75 &mut self,
76 _path: &Path,
77 _matcher_idx: usize,
78 _token: Token,
79 ) -> Result<Option<Vec<u8>>, error::Handler> {
80 self.used = 0;
82
83 Ok(None)
84 }
85
86 fn feed(
87 &mut self,
88 data: &[u8],
89 _matcher_idx: usize,
90 ) -> Result<Option<Vec<u8>>, error::Handler> {
91 if self.used >= self.max_length {
93 return Ok(None);
94 }
95
96 if data.len() <= (self.max_length - self.used) {
98 self.used += data.len();
99 return Ok(Some(data.to_vec()));
100 }
101
102 let result: Vec<u8> = data[..(self.max_length - self.used + 1)]
104 .iter()
105 .cloned()
106 .chain(self.terminator.as_bytes().iter().cloned())
107 .collect();
108
109 self.used = self.max_length;
110
111 Ok(Some(result))
112 }
113
114 fn is_converter(&self) -> bool {
115 true
116 }
117
118 fn as_any(&self) -> &dyn Any {
119 self
120 }
121}
122
123#[cfg(test)]
124mod tests {
125 use super::Shorten;
126 use crate::{
127 matcher::Simple,
128 strategy::{Convert, OutputConverter, Strategy},
129 };
130 use std::sync::{Arc, Mutex};
131
132 #[test]
133 fn shorten_handler() {
134 let mut convert = Convert::new();
135 let shorten_handler = Arc::new(Mutex::new(Shorten::new(10, "..\"".to_string())));
136 let matcher = Simple::new(r#"[]{"description"}"#).unwrap();
137
138 convert.add_matcher(Box::new(matcher), shorten_handler.clone());
139 let output: Vec<u8> = OutputConverter::new()
140 .convert(
141 &convert
142 .process(
143 br#"[{"description": "too long description"}, {"description": "short"}]"#,
144 )
145 .unwrap(),
146 )
147 .into_iter()
148 .map(|e| e.1)
149 .flatten()
150 .collect();
151
152 assert_eq!(
153 String::from_utf8(output).unwrap(),
154 r#"[{"description": "too long d.."}, {"description": "short"}]"#
155 );
156 }
157
158 #[test]
159 fn shorten_handler_parts() {
160 let mut convert = Convert::new();
161 let shorten_handler = Arc::new(Mutex::new(Shorten::new(10, "..\"".to_string())));
162 let matcher = Simple::new(r#"[]{"description"}"#).unwrap();
163
164 convert.add_matcher(Box::new(matcher), shorten_handler.clone());
165 let mut output = convert.process(br#"[{"description": "t"#).unwrap();
166
167 output.extend(convert.process(br#"oo long d"#).unwrap());
168
169 output.extend(
170 convert
171 .process(br#"escription"}, {"description": "short"}]"#)
172 .unwrap(),
173 );
174
175 let output: Vec<u8> = OutputConverter::new()
176 .convert(&output)
177 .into_iter()
178 .map(|e| e.1)
179 .flatten()
180 .collect();
181
182 assert_eq!(
183 String::from_utf8(output).unwrap(),
184 r#"[{"description": "too long d.."}, {"description": "short"}]"#
185 );
186 }
187}