1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//! Handler which puts output into stdout
//!
use super::Handler;
use crate::{error, path::Path};
use std::str;

/// Handler responsible for sending data to stdout.
pub struct PrintLn {
    /// Indicator whether the path will be displayed
    /// e.g. `{"items"}: {"sub": 4}` vs `{"sub": 4}`
    use_path: bool,

    /// String which will be appended to the end of each record
    /// to separate it with the next record (default '#')
    separator: String,
}

impl Default for PrintLn {
    fn default() -> Self {
        Self {
            use_path: false,
            separator: "\n".into(),
        }
    }
}

impl PrintLn {
    /// Creates new handler which output items to stdout.
    pub fn new() -> Self {
        Self::default()
    }

    /// Set whether to show path
    ///
    /// # Arguments
    /// * `use_path` - should path be shown in the output
    ///
    /// # Example
    /// ```
    /// use streamson_lib::handler;
    /// let file = handler::PrintLn::new().set_use_path(true);
    /// ```
    pub fn set_use_path(mut self, use_path: bool) -> Self {
        self.use_path = use_path;
        self
    }

    /// Set which separator will be used in the output
    ///
    /// Note that every separator will be extended to every found item.
    ///
    /// # Arguments
    /// * `separator` - how found record will be separated
    ///
    /// # Example
    ///
    /// ```
    /// use streamson_lib::handler;
    /// let file = handler::PrintLn::new().set_separator("######\n");
    /// ```
    pub fn set_separator<S>(mut self, separator: S) -> Self
    where
        S: ToString,
    {
        self.separator = separator.to_string();
        self
    }
}

impl Handler for PrintLn {
    fn use_path(&self) -> bool {
        self.use_path
    }

    fn separator(&self) -> &str {
        &self.separator
    }

    fn handle(
        &mut self,
        path: &Path,
        _matcher_idx: usize,
        data: Option<&[u8]>,
    ) -> Result<Option<Vec<u8>>, error::Handler> {
        let str_data =
            str::from_utf8(data.unwrap()).map_err(|err| error::Handler::new(err.to_string()))?;
        if self.use_path() {
            print!("{}: {}{}", path, str_data, self.separator());
        } else {
            print!("{}{}", str_data, self.separator());
        }

        Ok(None)
    }
}