11use crate :: timestamp:: Timestamp ;
2- use memchr:: memchr;
32use std:: borrow:: Cow ;
43use std:: time:: Duration ;
54
5+ #[ derive( Clone , Eq , PartialEq , Hash , Debug ) ]
6+ pub struct Argument < ' a > {
7+ pub name : Option < Cow < ' a , str > > ,
8+ pub value : Cow < ' a , str > ,
9+ }
10+
11+ impl < ' a > Argument < ' a > {
12+ pub fn new ( value : & ' a str ) -> Self {
13+ Self { name : None , value : Cow :: from ( value) }
14+ }
15+
16+ pub fn new_named ( name : & ' a str , value : & ' a str ) -> Self {
17+ Self { name : Some ( Cow :: from ( name) ) , value : Cow :: from ( value) }
18+ }
19+ }
20+
621#[ derive( Clone , Eq , PartialEq , Hash , Debug ) ]
722pub struct Event < ' a > {
823 pub event_kind : Cow < ' a , str > ,
924 pub label : Cow < ' a , str > ,
10- pub additional_data : Vec < Cow < ' a , str > > ,
25+ pub additional_data : Vec < Argument < ' a > > ,
1126 pub timestamp : Timestamp ,
1227 pub thread_id : u32 ,
1328}
@@ -38,7 +53,7 @@ impl<'a> Event<'a> {
3853 }
3954 }
4055
41- pub ( crate ) fn parse_event_id ( event_id : Cow < ' a , str > ) -> ( Cow < ' a , str > , Vec < Cow < ' a , str > > ) {
56+ pub ( crate ) fn parse_event_id ( event_id : Cow < ' a , str > ) -> ( Cow < ' a , str > , Vec < Argument < ' a > > ) {
4257 let event_id = match event_id {
4358 Cow :: Owned ( s) => Cow :: Owned ( s. into_bytes ( ) ) ,
4459 Cow :: Borrowed ( s) => Cow :: Borrowed ( s. as_bytes ( ) ) ,
@@ -75,52 +90,58 @@ struct Parser<'a> {
7590 pos : usize ,
7691}
7792
78- const SEPARATOR_BYTE : u8 = measureme:: event_id:: SEPARATOR_BYTE . as_bytes ( ) [ 0 ] ;
93+ const ARGUMENT_VALUE_TAG_BYTE : u8 = measureme:: event_id:: ARGUMENT_VALUE_TAG_BYTE . as_bytes ( ) [ 0 ] ;
94+ const ARGUMENT_NAME_TAG_BYTE : u8 = measureme:: event_id:: ARGUMENT_NAME_TAG_BYTE . as_bytes ( ) [ 0 ] ;
7995
8096impl < ' a > Parser < ' a > {
8197 fn new ( full_text : Cow < ' a , [ u8 ] > ) -> Parser < ' a > {
8298 Parser { full_text, pos : 0 }
8399 }
84100
85- fn peek ( & self ) -> u8 {
86- self . full_text [ self . pos ]
87- }
88-
89101 fn parse_label ( & mut self ) -> Result < Cow < ' a , str > , String > {
90102 assert ! ( self . pos == 0 ) ;
91- self . parse_separator_terminated_text ( )
103+ let text = self . parse_text ( ) ?;
104+ if text. is_empty ( ) {
105+ return self . err ( "<label> is empty" ) ;
106+ } else {
107+ Ok ( text)
108+ }
92109 }
93110
94- fn parse_separator_terminated_text ( & mut self ) -> Result < Cow < ' a , str > , String > {
111+ fn parse_text ( & mut self ) -> Result < Cow < ' a , str > , String > {
95112 let start = self . pos ;
96-
97- let end = memchr ( SEPARATOR_BYTE , & self . full_text [ start..] )
98- . map ( |pos| pos + start)
99- . unwrap_or ( self . full_text . len ( ) ) ;
100-
101- if start == end {
102- return self . err ( "Zero-length <text>" ) ;
103- }
104-
105- self . pos = end;
106-
107- if self . full_text [ start..end] . iter ( ) . any ( u8:: is_ascii_control) {
108- return self . err ( "Found ASCII control character in <text>" ) ;
109- }
110-
111- Ok ( self . substring ( start, end) )
113+ self . pos += self . full_text [ start..]
114+ . iter ( )
115+ . take_while ( |c| !u8:: is_ascii_control ( c) )
116+ . count ( ) ;
117+ Ok ( self . substring ( start, self . pos ) )
112118 }
113119
114- fn parse_arg ( & mut self ) -> Result < Cow < ' a , str > , String > {
115- if self . peek ( ) != SEPARATOR_BYTE {
116- return self . err ( & format ! (
117- "Expected '\\ x{:x}' char at start of <argument>" ,
118- SEPARATOR_BYTE
119- ) ) ;
120+ fn parse_arg ( & mut self ) -> Result < Argument < ' a > , String > {
121+ let name = if let Some ( & byte) = self . full_text . get ( self . pos ) {
122+ if byte == ARGUMENT_NAME_TAG_BYTE {
123+ self . pos += 1 ;
124+ Some ( self . parse_text ( ) ?)
125+ } else {
126+ None
127+ }
128+ } else {
129+ None
130+ } ;
131+ let value = if let Some ( & byte) = self . full_text . get ( self . pos ) {
132+ if byte == ARGUMENT_VALUE_TAG_BYTE {
133+ self . pos += 1 ;
134+ Some ( self . parse_text ( ) ?)
135+ } else {
136+ None
137+ }
138+ } else {
139+ None
140+ } ;
141+ match ( name, value) {
142+ ( name, Some ( value) ) => Ok ( Argument { name, value } ) ,
143+ ( _, None ) => self . err ( "Unable to parse required <argument_value>" ) ,
120144 }
121-
122- self . pos += 1 ;
123- self . parse_separator_terminated_text ( )
124145 }
125146
126147 fn err < T > ( & self , message : & str ) -> Result < T , String > {
@@ -161,7 +182,7 @@ mod tests {
161182 let ( label, args) = Event :: parse_event_id ( Cow :: from ( "foo\x1e my_arg" ) ) ;
162183
163184 assert_eq ! ( label, "foo" ) ;
164- assert_eq ! ( args, vec![ Cow :: from ( "my_arg" ) ] ) ;
185+ assert_eq ! ( args, vec![ Argument :: new ( "my_arg" ) ] ) ;
165186 }
166187
167188 #[ test]
@@ -171,7 +192,21 @@ mod tests {
171192 assert_eq ! ( label, "foo" ) ;
172193 assert_eq ! (
173194 args,
174- vec![ Cow :: from( "arg1" ) , Cow :: from( "arg2" ) , Cow :: from( "arg3" ) ]
195+ vec![ Argument :: new( "arg1" ) , Argument :: new( "arg2" ) , Argument :: new( "arg3" ) ]
196+ ) ;
197+ }
198+
199+ #[ test]
200+ fn parse_event_id_n_named_args ( ) {
201+ let ( label, args) = Event :: parse_event_id ( Cow :: from ( "foo\x1d arg1\x1e val1\x1d arg2\x1e val2" ) ) ;
202+
203+ assert_eq ! ( label, "foo" ) ;
204+ assert_eq ! (
205+ args,
206+ vec![
207+ Argument :: new_named( "arg1" , "val1" ) ,
208+ Argument :: new_named( "arg2" , "val2" ) ,
209+ ]
175210 ) ;
176211 }
177212}
0 commit comments