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 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
mod error; pub mod parser; pub use error::Error; pub(crate) type NomRes<T, U> = nom::IResult<T, U, nom::error::VerboseError<T>>; #[cfg(not(feature = "serde-serialize"))] pub trait ParsePart<'a> { fn parse(msg: &'a str) -> Result<(&'a str, Self), Error> where Self: Sized; } #[cfg(feature = "serde-serialize")] pub trait ParsePart<'a>: serde::Serialize { fn parse(msg: &'a str) -> Result<(&'a str, Self), Error> where Self: Sized; } #[derive(Debug, Eq, PartialEq)] #[cfg_attr(feature = "serde-serialize", derive(serde::Serialize))] pub struct Message< 'a, T = Option<&'a str>, S = Vec<parser::StructuredData<'a>>, M = parser::msg::Raw<'a>, > where T: ParsePart<'a>, S: ParsePart<'a>, M: ParseMsg<'a>, { pub facility: u8, pub severity: u8, pub version: u8, pub timestamp: T, pub hostname: Option<&'a str>, pub app_name: Option<&'a str>, pub proc_id: Option<&'a str>, pub msg_id: Option<&'a str>, pub structured_data: S, pub msg: M, } impl<'a, T, S, M> Message<'a, T, S, M> where T: ParsePart<'a>, S: ParsePart<'a>, M: ParseMsg<'a>, { pub fn parse(msg: &'a str) -> Result<Message<'a, T, S, M>, Error<'a>> { parser::parse(msg).map(|tuple| tuple.1) } pub fn parse_with_rem(msg: &'a str) -> Result<(&'a str, Message<'a, T, S, M>), Error<'a>> { parser::parse(msg) } pub fn iter(msg: &'a str) -> MessageIter<'a, T, S, M> { MessageIter { rem: msg, found_error: false, t: std::marker::PhantomData, s: std::marker::PhantomData, m: std::marker::PhantomData, } } } pub struct MessageIter<'a, T, S, M> where T: ParsePart<'a>, S: ParsePart<'a>, M: ParseMsg<'a>, { rem: &'a str, found_error: bool, t: std::marker::PhantomData<T>, s: std::marker::PhantomData<S>, m: std::marker::PhantomData<M>, } impl<'a, T, S, M> Iterator for MessageIter<'a, T, S, M> where T: ParsePart<'a>, S: ParsePart<'a>, M: ParseMsg<'a>, { type Item = Result<Message<'a, T, S, M>, Error<'a>>; fn next(&mut self) -> Option<Self::Item> { if self.found_error { return None; } if self.rem.is_empty() { return None; } let res = Message::parse_with_rem(self.rem); match res { Err(err) => Some(Err(err)), Ok((rem, msg)) => { self.rem = rem; Some(Ok(msg)) } } } } pub struct Originator<'a> { pub hostname: Option<&'a str>, pub app_name: Option<&'a str>, pub proc_id: Option<&'a str>, pub msg_id: Option<&'a str>, } pub trait ParseMsg<'a> { fn parse(msg: &'a str, foo: &Originator<'a>) -> Result<(&'a str, Self), Error<'a>> where Self: Sized; }