@@ -78,99 +78,125 @@ pub enum ByteRepresentation {
78
78
Range ( ( usize , usize ) ) ,
79
79
}
80
80
81
- #[ derive( Debug , Clone ) ]
82
- pub enum ParseErrorType {
83
- Fmt ( String ) ,
84
- Other ( String ) ,
81
+ #[ derive( Debug ) ]
82
+ pub enum MessageStreamItem < T : LogMessage > {
83
+ Item ( ParseYield < T > ) ,
84
+ Skipped ,
85
+ Incomplete ,
86
+ Empty ,
87
+ Done ,
85
88
}
86
89
87
- #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
88
- /// Gives Hint about how this error can be resolved by processor
89
- pub enum ResolveErrorHint {
90
- /// The message needs to be parsed with SomeIP Parser.
91
- SomeIP ,
90
+ pub trait LogMessage : Serialize {
91
+ /// Serializes a message directly into a Writer
92
+ /// returns the size of the serialized message
93
+ fn to_writer < W : Write > ( & self , writer : & mut W ) -> Result < usize , std:: io:: Error > ;
94
+
95
+ /// Tries to resolve the message to get its text representation.
96
+ ///
97
+ /// TODO: This function should return another optional field, containing information
98
+ /// about errors, warning ...
99
+ fn try_resolve ( & self ) -> LogMessageContent ;
92
100
}
93
101
94
102
#[ derive( Debug , Clone ) ]
95
- pub struct ParseLogError {
96
- pub remain_bytes : Vec < u8 > ,
97
- pub error_type : ParseErrorType ,
98
- pub resolve_hint : Option < ResolveErrorHint > ,
99
- }
100
-
101
- impl ParseLogError {
102
- pub fn new (
103
- remain_bytes : Vec < u8 > ,
104
- error_type : ParseErrorType ,
105
- resolve_hint : Option < ResolveErrorHint > ,
106
- ) -> Self {
107
- Self {
108
- remain_bytes,
109
- error_type,
110
- resolve_hint,
111
- }
112
- }
103
+ /// Represents The content of a log message after trying to resolve it.
104
+ pub enum LogMessageContent {
105
+ Text ( String ) ,
106
+ Template ( TemplateLogMsg ) ,
113
107
}
114
108
115
- impl Display for ParseLogError {
116
- fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
117
- match & self . error_type {
118
- ParseErrorType :: Other ( msg) | ParseErrorType :: Fmt ( msg) => write ! ( f, "{msg}" ) ,
119
- }
120
- }
109
+ #[ derive( Debug , Clone ) ]
110
+ /// Represents an unresolved log messages that contains chunks that needs to be resolved.
111
+ pub struct TemplateLogMsg {
112
+ chunks : Vec < TemplateLogMsgChunk > ,
113
+ resolve_hints : Vec < ResolveParseHint > ,
121
114
}
122
115
123
- impl From < std:: fmt:: Error > for ParseLogError {
124
- fn from ( value : std:: fmt:: Error ) -> Self {
125
- Self {
126
- remain_bytes : Vec :: new ( ) ,
127
- error_type : ParseErrorType :: Fmt ( value. to_string ( ) ) ,
128
- resolve_hint : None ,
129
- }
130
- }
116
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
117
+ /// Gives Hint about how the payload rest can be resolved
118
+ pub enum ResolveParseHint {
119
+ /// The message needs to be parsed with SomeIP Parser.
120
+ SomeIP ,
131
121
}
132
122
133
- impl std:: error:: Error for ParseLogError { }
134
-
135
123
#[ derive( Debug , Clone ) ]
136
- pub struct ToTextResult {
137
- pub msg : String ,
138
- pub error : Option < ParseLogError > ,
139
- }
140
-
141
- impl ToTextResult {
142
- pub fn new ( msg : String , error : Option < ParseLogError > ) -> Self {
143
- Self { msg, error }
144
- }
124
+ /// Represents a chunk in [`TemplateLogMsg`]
125
+ pub enum TemplateLogMsgChunk {
126
+ /// Resolved Chunk
127
+ Text ( String ) ,
128
+ /// Unresolved Chunk
129
+ Bytes ( Vec < u8 > ) ,
145
130
}
146
131
147
- impl < T > From < T > for ToTextResult
132
+ impl < T > From < T > for LogMessageContent
148
133
where
149
134
T : Display ,
150
135
{
151
136
fn from ( value : T ) -> Self {
152
- Self :: new ( value. to_string ( ) , None )
137
+ Self :: Text ( value. to_string ( ) )
153
138
}
154
139
}
155
140
156
- pub trait LogMessage : Serialize {
157
- //TODO AAZ: Measure this an remove if rust already optimize the code without it.
158
- /// Indicates that parsing this struct to text can error.
159
- const CAN_ERROR : bool ;
141
+ impl TemplateLogMsg {
142
+ pub fn new ( chunks : Vec < TemplateLogMsgChunk > , resolve_hints : Vec < ResolveParseHint > ) -> Self {
143
+ Self {
144
+ chunks,
145
+ resolve_hints,
146
+ }
147
+ }
160
148
161
- /// Serializes a message directly into a Writer
162
- /// returns the size of the serialized message
163
- fn to_writer < W : Write > ( & self , writer : & mut W ) -> Result < usize , std :: io :: Error > ;
149
+ pub fn get_resolve_hints ( & self ) -> Vec < ResolveParseHint > {
150
+ self . resolve_hints . to_vec ( )
151
+ }
164
152
165
- /// Get the text representation of this message.
166
- fn to_text ( & self ) -> ToTextResult ;
167
- }
153
+ /// Applies the given [`FnMut`] on the unresolved chunks, replacing them with texts if succeed.
154
+ /// This function will return a String once chunks get resolved.
155
+ ///
156
+ /// * `parse_fn`: Function to apply on the unresolved chunks.
157
+ pub fn try_resolve < F > ( & mut self , mut parse_fn : F ) -> Option < String >
158
+ where
159
+ F : FnMut ( & [ u8 ] ) -> Option < String > ,
160
+ {
161
+ let mut all_resolved = true ;
162
+ for ch in self . chunks . iter_mut ( ) {
163
+ match ch {
164
+ TemplateLogMsgChunk :: Text ( _) => continue ,
165
+ TemplateLogMsgChunk :: Bytes ( bytes) => match parse_fn ( & bytes) {
166
+ Some ( resolved) => * ch = TemplateLogMsgChunk :: Text ( resolved) ,
167
+ None => all_resolved = false ,
168
+ } ,
169
+ }
170
+ }
168
171
169
- #[ derive( Debug ) ]
170
- pub enum MessageStreamItem < T : LogMessage > {
171
- Item ( ParseYield < T > ) ,
172
- Skipped ,
173
- Incomplete ,
174
- Empty ,
175
- Done ,
172
+ if all_resolved {
173
+ self . chunks
174
+ . iter ( )
175
+ . map ( |ch| match ch {
176
+ TemplateLogMsgChunk :: Text ( msg) => msg,
177
+ TemplateLogMsgChunk :: Bytes ( _) => panic ! ( "All must be resolved" ) ,
178
+ } )
179
+ . cloned ( )
180
+ . reduce ( |mut acc, msg| {
181
+ acc. push_str ( & msg) ;
182
+ acc
183
+ } )
184
+ } else {
185
+ None
186
+ }
187
+ }
188
+
189
+ /// Concatenates the chunks to a string, replacing the unresolved chunks with their bytes
190
+ /// representation.
191
+ pub fn resolve_lossy ( self ) -> String {
192
+ self . chunks
193
+ . into_iter ( )
194
+ . fold ( String :: new ( ) , |mut acc, ch| match ch {
195
+ TemplateLogMsgChunk :: Text ( msg) => {
196
+ acc. push_str ( & msg) ;
197
+ acc
198
+ }
199
+ TemplateLogMsgChunk :: Bytes ( bytes) => format ! ( "{acc} {bytes:?}" ) ,
200
+ } )
201
+ }
176
202
}
0 commit comments