oxedyne/fe2o3/fe2o3_text/tests/annealer_corpus/nom_bytes.rs
31.0 KiB, 1 run
created by r1870400018:11752, which is this file's identity for as long as the history lasts, whatever it is later renamed to
download · who wrote it · its history
| 1 | //! Parsers recognizing bytes streams |
| 2 | |
| 3 | pub mod complete; |
| 4 | pub mod streaming; |
| 5 | #[cfg(test)] |
| 6 | mod tests; |
| 7 | |
| 8 | use core::marker::PhantomData; |
| 9 | |
| 10 | use crate::error::ErrorKind; |
| 11 | use crate::error::ParseError; |
| 12 | use crate::internal::{Err, Needed, Parser}; |
| 13 | use crate::lib::std::result::Result::*; |
| 14 | use crate::traits::{Compare, CompareResult}; |
| 15 | use crate::AsChar; |
| 16 | use crate::Check; |
| 17 | use crate::ExtendInto; |
| 18 | use crate::FindSubstring; |
| 19 | use crate::FindToken; |
| 20 | use crate::Input; |
| 21 | use crate::IsStreaming; |
| 22 | use crate::Mode; |
| 23 | use crate::OutputM; |
| 24 | use crate::OutputMode; |
| 25 | use crate::ToUsize; |
| 26 | |
| 27 | /// Recognizes a pattern. |
| 28 | /// |
| 29 | /// The input data will be compared to the tag combinator's argument and will return the part of |
| 30 | /// the input that matches the argument. |
| 31 | /// # Example |
| 32 | /// ```rust |
| 33 | /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; |
| 34 | /// use nom::bytes::streaming::tag; |
| 35 | /// |
| 36 | /// fn parser(s: &str) -> IResult<&str, &str> { |
| 37 | /// tag("Hello")(s) |
| 38 | /// } |
| 39 | /// |
| 40 | /// assert_eq!(parser("Hello, World!"), Ok((", World!", "Hello"))); |
| 41 | /// assert_eq!(parser("Something"), Err(Err::Error(Error::new("Something", ErrorKind::Tag)))); |
| 42 | /// assert_eq!(parser("S"), Err(Err::Error(Error::new("S", ErrorKind::Tag)))); |
| 43 | /// assert_eq!(parser("H"), Err(Err::Incomplete(Needed::new(4)))); |
| 44 | /// ``` |
| 45 | pub fn tag<T, I, Error: ParseError<I>>(tag: T) -> impl Parser<I, Output = I, Error = Error> |
| 46 | where |
| 47 | I: Input + Compare<T>, |
| 48 | T: Input + Clone, |
| 49 | { |
| 50 | Tag { |
| 51 | tag, |
| 52 | e: PhantomData, |
| 53 | } |
| 54 | } |
| 55 | |
| 56 | /// Tag implementation |
| 57 | pub struct Tag<T, E> { |
| 58 | tag: T, |
| 59 | e: PhantomData<E>, |
| 60 | } |
| 61 | |
| 62 | impl<I, Error: ParseError<I>, T> Parser<I> for Tag<T, Error> |
| 63 | where |
| 64 | I: Input + Compare<T>, |
| 65 | T: Input + Clone, |
| 66 | { |
| 67 | type Output = I; |
| 68 | |
| 69 | type Error = Error; |
| 70 | |
| 71 | fn process<OM: OutputMode>(&mut self, i: I) -> crate::PResult<OM, I, Self::Output, Self::Error> { |
| 72 | let tag_len = self.tag.input_len(); |
| 73 | let t = self.tag.clone(); |
| 74 | |
| 75 | match i.compare(t) { |
| 76 | CompareResult::Ok => Ok((i.take_from(tag_len), OM::Output::bind(|| i.take(tag_len)))), |
| 77 | CompareResult::Incomplete => { |
| 78 | if OM::Incomplete::is_streaming() { |
| 79 | Err(Err::Incomplete(Needed::new(tag_len - i.input_len()))) |
| 80 | } else { |
| 81 | Err(Err::Error(OM::Error::bind(|| { |
| 82 | let e: ErrorKind = ErrorKind::Tag; |
| 83 | Error::from_error_kind(i, e) |
| 84 | }))) |
| 85 | } |
| 86 | } |
| 87 | CompareResult::Error => Err(Err::Error(OM::Error::bind(|| { |
| 88 | let e: ErrorKind = ErrorKind::Tag; |
| 89 | Error::from_error_kind(i, e) |
| 90 | }))), |
| 91 | } |
| 92 | } |
| 93 | } |
| 94 | |
| 95 | /// Recognizes a case insensitive pattern. |
| 96 | /// |
| 97 | /// The input data will be compared to the tag combinator's argument and will return the part of |
| 98 | /// the input that matches the argument with no regard to case. |
| 99 | /// # Example |
| 100 | /// ```rust |
| 101 | /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; |
| 102 | /// use nom::bytes::streaming::tag_no_case; |
| 103 | /// |
| 104 | /// fn parser(s: &str) -> IResult<&str, &str> { |
| 105 | /// tag_no_case("hello")(s) |
| 106 | /// } |
| 107 | /// |
| 108 | /// assert_eq!(parser("Hello, World!"), Ok((", World!", "Hello"))); |
| 109 | /// assert_eq!(parser("hello, World!"), Ok((", World!", "hello"))); |
| 110 | /// assert_eq!(parser("HeLlO, World!"), Ok((", World!", "HeLlO"))); |
| 111 | /// assert_eq!(parser("Something"), Err(Err::Error(Error::new("Something", ErrorKind::Tag)))); |
| 112 | /// assert_eq!(parser(""), Err(Err::Incomplete(Needed::new(5)))); |
| 113 | /// ``` |
| 114 | pub fn tag_no_case<T, I, Error: ParseError<I>>(tag: T) -> impl Parser<I, Output = I, Error = Error> |
| 115 | where |
| 116 | I: Input + Compare<T>, |
| 117 | T: Input + Clone, |
| 118 | { |
| 119 | TagNoCase { |
| 120 | tag, |
| 121 | e: PhantomData, |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | /// Case insensitive Tag implementation |
| 126 | pub struct TagNoCase<T, E> { |
| 127 | tag: T, |
| 128 | e: PhantomData<E>, |
| 129 | } |
| 130 | |
| 131 | impl<I, Error: ParseError<I>, T> Parser<I> for TagNoCase<T, Error> |
| 132 | where |
| 133 | I: Input + Compare<T>, |
| 134 | T: Input + Clone, |
| 135 | { |
| 136 | type Output = I; |
| 137 | |
| 138 | type Error = Error; |
| 139 | |
| 140 | fn process<OM: OutputMode>(&mut self, i: I) -> crate::PResult<OM, I, Self::Output, Self::Error> { |
| 141 | let tag_len = self.tag.input_len(); |
| 142 | let t = self.tag.clone(); |
| 143 | |
| 144 | match i.compare_no_case(t) { |
| 145 | CompareResult::Ok => Ok((i.take_from(tag_len), OM::Output::bind(|| i.take(tag_len)))), |
| 146 | CompareResult::Incomplete => { |
| 147 | if OM::Incomplete::is_streaming() { |
| 148 | Err(Err::Incomplete(Needed::new(tag_len - i.input_len()))) |
| 149 | } else { |
| 150 | Err(Err::Error(OM::Error::bind(|| { |
| 151 | let e: ErrorKind = ErrorKind::Tag; |
| 152 | Error::from_error_kind(i, e) |
| 153 | }))) |
| 154 | } |
| 155 | } |
| 156 | CompareResult::Error => Err(Err::Error(OM::Error::bind(|| { |
| 157 | let e: ErrorKind = ErrorKind::Tag; |
| 158 | Error::from_error_kind(i, e) |
| 159 | }))), |
| 160 | } |
| 161 | } |
| 162 | } |
| 163 | |
| 164 | /// Parser wrapper for `split_at_position` |
| 165 | pub struct SplitPosition<F, E> { |
| 166 | predicate: F, |
| 167 | error: PhantomData<E>, |
| 168 | } |
| 169 | |
| 170 | impl<I, Error: ParseError<I>, F> Parser<I> for SplitPosition<F, Error> |
| 171 | where |
| 172 | I: Input, |
| 173 | F: Fn(<I as Input>::Item) -> bool, |
| 174 | { |
| 175 | type Output = I; |
| 176 | |
| 177 | type Error = Error; |
| 178 | |
| 179 | #[inline(always)] |
| 180 | fn process<OM: OutputMode>(&mut self, i: I) -> crate::PResult<OM, I, Self::Output, Self::Error> { |
| 181 | i.split_at_position_mode::<OM, _, _>(|c| (self.predicate)(c)) |
| 182 | } |
| 183 | } |
| 184 | |
| 185 | /// Parser wrapper for `split_at_position1` |
| 186 | pub struct SplitPosition1<F, E> { |
| 187 | e: ErrorKind, |
| 188 | predicate: F, |
| 189 | error: PhantomData<E>, |
| 190 | } |
| 191 | |
| 192 | impl<I, Error: ParseError<I>, F> Parser<I> for SplitPosition1<F, Error> |
| 193 | where |
| 194 | I: Input, |
| 195 | F: Fn(<I as Input>::Item) -> bool, |
| 196 | { |
| 197 | type Output = I; |
| 198 | |
| 199 | type Error = Error; |
| 200 | |
| 201 | #[inline(always)] |
| 202 | fn process<OM: OutputMode>(&mut self, i: I) -> crate::PResult<OM, I, Self::Output, Self::Error> { |
| 203 | i.split_at_position_mode1::<OM, _, _>(|c| (self.predicate)(c), self.e) |
| 204 | } |
| 205 | } |
| 206 | |
| 207 | /// Parse till certain characters are met. |
| 208 | /// |
| 209 | /// The parser will return the longest slice till one of the characters of the combinator's argument are met. |
| 210 | /// |
| 211 | /// It doesn't consume the matched character. |
| 212 | /// |
| 213 | /// It will return a `Err::Error(("", ErrorKind::IsNot))` if the pattern wasn't met. |
| 214 | /// # Example |
| 215 | /// ```rust |
| 216 | /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; |
| 217 | /// use nom::bytes::complete::is_not; |
| 218 | /// |
| 219 | /// fn not_space(s: &str) -> IResult<&str, &str> { |
| 220 | /// is_not(" \t\r\n")(s) |
| 221 | /// } |
| 222 | /// |
| 223 | /// assert_eq!(not_space("Hello, World!"), Ok((" World!", "Hello,"))); |
| 224 | /// assert_eq!(not_space("Sometimes\t"), Ok(("\t", "Sometimes"))); |
| 225 | /// assert_eq!(not_space("Nospace"), Ok(("", "Nospace"))); |
| 226 | /// assert_eq!(not_space(""), Err(Err::Error(Error::new("", ErrorKind::IsNot)))); |
| 227 | /// ``` |
| 228 | pub fn is_not<T, I, Error: ParseError<I>>(arr: T) -> impl Parser<I, Output = I, Error = Error> |
| 229 | where |
| 230 | I: Input, |
| 231 | T: FindToken<<I as Input>::Item>, |
| 232 | { |
| 233 | SplitPosition1 { |
| 234 | e: ErrorKind::IsNot, |
| 235 | predicate: move |c| arr.find_token(c), |
| 236 | error: PhantomData, |
| 237 | } |
| 238 | } |
| 239 | |
| 240 | /// Returns the longest input slice (at least 1) that matches the pattern. |
| 241 | /// |
| 242 | /// The parser will return the longest slice consisting of the characters in provided in the |
| 243 | /// combinator's argument. |
| 244 | /// |
| 245 | /// It will return a `Err(Err::Error((_, ErrorKind::IsA)))` if the pattern wasn't met. |
| 246 | /// # Example |
| 247 | /// ```rust |
| 248 | /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; |
| 249 | /// use nom::bytes::complete::is_a; |
| 250 | /// |
| 251 | /// fn hex(s: &str) -> IResult<&str, &str> { |
| 252 | /// is_a("1234567890ABCDEF")(s) |
| 253 | /// } |
| 254 | /// |
| 255 | /// assert_eq!(hex("123 and voila"), Ok((" and voila", "123"))); |
| 256 | /// assert_eq!(hex("DEADBEEF and others"), Ok((" and others", "DEADBEEF"))); |
| 257 | /// assert_eq!(hex("BADBABEsomething"), Ok(("something", "BADBABE"))); |
| 258 | /// assert_eq!(hex("D15EA5E"), Ok(("", "D15EA5E"))); |
| 259 | /// assert_eq!(hex(""), Err(Err::Error(Error::new("", ErrorKind::IsA)))); |
| 260 | /// ``` |
| 261 | pub fn is_a<T, I, Error: ParseError<I>>(arr: T) -> impl Parser<I, Output = I, Error = Error> |
| 262 | where |
| 263 | I: Input, |
| 264 | T: FindToken<<I as Input>::Item>, |
| 265 | { |
| 266 | SplitPosition1 { |
| 267 | e: ErrorKind::IsA, |
| 268 | predicate: move |c| !arr.find_token(c), |
| 269 | error: PhantomData, |
| 270 | } |
| 271 | } |
| 272 | |
| 273 | /// Returns the longest input slice (if any) that matches the predicate. |
| 274 | /// |
| 275 | /// The parser will return the longest slice that matches the given predicate *(a function that |
| 276 | /// takes the input and returns a bool)*. |
| 277 | /// # Example |
| 278 | /// ```rust |
| 279 | /// # use nom::{Err, error::ErrorKind, Needed, IResult}; |
| 280 | /// use nom::bytes::complete::take_while; |
| 281 | /// use nom::AsChar; |
| 282 | /// |
| 283 | /// fn alpha(s: &[u8]) -> IResult<&[u8], &[u8]> { |
| 284 | /// take_while(AsChar::is_alpha)(s) |
| 285 | /// } |
| 286 | /// |
| 287 | /// assert_eq!(alpha(b"latin123"), Ok((&b"123"[..], &b"latin"[..]))); |
| 288 | /// assert_eq!(alpha(b"12345"), Ok((&b"12345"[..], &b""[..]))); |
| 289 | /// assert_eq!(alpha(b"latin"), Ok((&b""[..], &b"latin"[..]))); |
| 290 | /// assert_eq!(alpha(b""), Ok((&b""[..], &b""[..]))); |
| 291 | /// ``` |
| 292 | pub fn take_while<F, I, Error: ParseError<I>>(cond: F) -> impl Parser<I, Output = I, Error = Error> |
| 293 | where |
| 294 | I: Input, |
| 295 | F: Fn(<I as Input>::Item) -> bool, |
| 296 | { |
| 297 | SplitPosition { |
| 298 | predicate: move |c| !cond(c), |
| 299 | error: PhantomData, |
| 300 | } |
| 301 | } |
| 302 | |
| 303 | /// Returns the longest (at least 1) input slice that matches the predicate. |
| 304 | /// |
| 305 | /// The parser will return the longest slice that matches the given predicate *(a function that |
| 306 | /// takes the input and returns a bool)*. |
| 307 | /// |
| 308 | /// It will return an `Err(Err::Error((_, ErrorKind::TakeWhile1)))` if the pattern wasn't met. |
| 309 | /// |
| 310 | /// # Streaming Specific |
| 311 | /// *Streaming version* will return a `Err::Incomplete(Needed::new(1))` or if the pattern reaches the end of the input. |
| 312 | /// |
| 313 | /// # Example |
| 314 | /// ```rust |
| 315 | /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; |
| 316 | /// use nom::bytes::streaming::take_while1; |
| 317 | /// use nom::AsChar; |
| 318 | /// |
| 319 | /// fn alpha(s: &[u8]) -> IResult<&[u8], &[u8]> { |
| 320 | /// take_while1(AsChar::is_alpha)(s) |
| 321 | /// } |
| 322 | /// |
| 323 | /// assert_eq!(alpha(b"latin123"), Ok((&b"123"[..], &b"latin"[..]))); |
| 324 | /// assert_eq!(alpha(b"latin"), Err(Err::Incomplete(Needed::new(1)))); |
| 325 | /// assert_eq!(alpha(b"12345"), Err(Err::Error(Error::new(&b"12345"[..], ErrorKind::TakeWhile1)))); |
| 326 | /// ``` |
| 327 | pub fn take_while1<F, I, Error: ParseError<I>>(cond: F) -> impl Parser<I, Output = I, Error = Error> |
| 328 | where |
| 329 | I: Input, |
| 330 | F: Fn(<I as Input>::Item) -> bool, |
| 331 | { |
| 332 | SplitPosition1 { |
| 333 | e: ErrorKind::TakeWhile1, |
| 334 | predicate: move |c| !cond(c), |
| 335 | error: PhantomData, |
| 336 | } |
| 337 | } |
| 338 | |
| 339 | /// Returns the longest (m <= len <= n) input slice that matches the predicate. |
| 340 | /// |
| 341 | /// The parser will return the longest slice that matches the given predicate *(a function that |
| 342 | /// takes the input and returns a bool)*. |
| 343 | /// |
| 344 | /// It will return an `Err::Error((_, ErrorKind::TakeWhileMN))` if the pattern wasn't met. |
| 345 | /// # Streaming Specific |
| 346 | /// *Streaming version* will return a `Err::Incomplete(Needed::new(1))` if the pattern reaches the end of the input or is too short. |
| 347 | /// |
| 348 | /// # Example |
| 349 | /// ```rust |
| 350 | /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; |
| 351 | /// use nom::bytes::streaming::take_while_m_n; |
| 352 | /// use nom::AsChar; |
| 353 | /// |
| 354 | /// fn short_alpha(s: &[u8]) -> IResult<&[u8], &[u8]> { |
| 355 | /// take_while_m_n(3, 6, AsChar::is_alpha)(s) |
| 356 | /// } |
| 357 | /// |
| 358 | /// assert_eq!(short_alpha(b"latin123"), Ok((&b"123"[..], &b"latin"[..]))); |
| 359 | /// assert_eq!(short_alpha(b"lengthy"), Ok((&b"y"[..], &b"length"[..]))); |
| 360 | /// assert_eq!(short_alpha(b"latin"), Err(Err::Incomplete(Needed::new(1)))); |
| 361 | /// assert_eq!(short_alpha(b"ed"), Err(Err::Incomplete(Needed::new(1)))); |
| 362 | /// assert_eq!(short_alpha(b"12345"), Err(Err::Error(Error::new(&b"12345"[..], ErrorKind::TakeWhileMN)))); |
| 363 | /// ``` |
| 364 | pub fn take_while_m_n<F, I, Error: ParseError<I>>( |
| 365 | m: usize, |
| 366 | n: usize, |
| 367 | predicate: F, |
| 368 | ) -> impl Parser<I, Output = I, Error = Error> |
| 369 | where |
| 370 | I: Input, |
| 371 | F: Fn(<I as Input>::Item) -> bool, |
| 372 | { |
| 373 | TakeWhileMN { |
| 374 | m, |
| 375 | n, |
| 376 | predicate, |
| 377 | e: PhantomData, |
| 378 | } |
| 379 | } |
| 380 | |
| 381 | /// Parser implementation for [take_while_m_n] |
| 382 | pub struct TakeWhileMN<F, E> { |
| 383 | m: usize, |
| 384 | n: usize, |
| 385 | predicate: F, |
| 386 | e: PhantomData<E>, |
| 387 | } |
| 388 | |
| 389 | impl<I, Error: ParseError<I>, F> Parser<I> for TakeWhileMN<F, Error> |
| 390 | where |
| 391 | I: Input, |
| 392 | F: Fn(<I as Input>::Item) -> bool, |
| 393 | { |
| 394 | type Output = I; |
| 395 | type Error = Error; |
| 396 | |
| 397 | fn process<OM: OutputMode>( |
| 398 | &mut self, |
| 399 | input: I, |
| 400 | ) -> crate::PResult<OM, I, Self::Output, Self::Error> { |
| 401 | let mut count = 0; |
| 402 | for (i, (index, item)) in input.iter_indices().enumerate() { |
| 403 | if i == self.n { |
| 404 | return Ok(( |
| 405 | input.take_from(index), |
| 406 | OM::Output::bind(|| input.take(index)), |
| 407 | )); |
| 408 | } |
| 409 | |
| 410 | if !(self.predicate)(item) { |
| 411 | if i >= self.m { |
| 412 | return Ok(( |
| 413 | input.take_from(index), |
| 414 | OM::Output::bind(|| input.take(index)), |
| 415 | )); |
| 416 | } else { |
| 417 | return Err(Err::Error(OM::Error::bind(|| { |
| 418 | Error::from_error_kind(input, ErrorKind::TakeWhileMN) |
| 419 | }))); |
| 420 | } |
| 421 | } |
| 422 | count += 1; |
| 423 | } |
| 424 | |
| 425 | let input_len = input.input_len(); |
| 426 | if OM::Incomplete::is_streaming() { |
| 427 | let needed = if self.m > input_len { |
| 428 | self.m - input_len |
| 429 | } else { |
| 430 | 1 |
| 431 | }; |
| 432 | Err(Err::Incomplete(Needed::new(needed))) |
| 433 | } else if count >= self.m { |
| 434 | Ok(( |
| 435 | input.take_from(input_len), |
| 436 | OM::Output::bind(|| input.take(input_len)), |
| 437 | )) |
| 438 | } else { |
| 439 | Err(Err::Error(OM::Error::bind(|| { |
| 440 | Error::from_error_kind(input, ErrorKind::TakeWhileMN) |
| 441 | }))) |
| 442 | } |
| 443 | } |
| 444 | } |
| 445 | |
| 446 | /// Returns the longest input slice (if any) till a predicate is met. |
| 447 | /// |
| 448 | /// The parser will return the longest slice till the given predicate *(a function that |
| 449 | /// takes the input and returns a bool)*. |
| 450 | /// # Example |
| 451 | /// ```rust |
| 452 | /// # use nom::{Err, error::ErrorKind, Needed, IResult}; |
| 453 | /// use nom::bytes::complete::take_till; |
| 454 | /// |
| 455 | /// fn till_colon(s: &str) -> IResult<&str, &str> { |
| 456 | /// take_till(|c| c == ':')(s) |
| 457 | /// } |
| 458 | /// |
| 459 | /// assert_eq!(till_colon("latin:123"), Ok((":123", "latin"))); |
| 460 | /// assert_eq!(till_colon(":empty matched"), Ok((":empty matched", ""))); //allowed |
| 461 | /// assert_eq!(till_colon("12345"), Ok(("", "12345"))); |
| 462 | /// assert_eq!(till_colon(""), Ok(("", ""))); |
| 463 | /// ``` |
| 464 | #[allow(clippy::redundant_closure)] |
| 465 | pub fn take_till<F, I, Error: ParseError<I>>(cond: F) -> impl Parser<I, Output = I, Error = Error> |
| 466 | where |
| 467 | I: Input, |
| 468 | F: Fn(<I as Input>::Item) -> bool, |
| 469 | { |
| 470 | SplitPosition { |
| 471 | predicate: cond, |
| 472 | error: PhantomData, |
| 473 | } |
| 474 | } |
| 475 | |
| 476 | /// Returns the longest (at least 1) input slice till a predicate is met. |
| 477 | /// |
| 478 | /// The parser will return the longest slice till the given predicate *(a function that |
| 479 | /// takes the input and returns a bool)*. |
| 480 | /// |
| 481 | /// # Streaming Specific |
| 482 | /// *Streaming version* will return a `Err::Incomplete(Needed::new(1))` if the match reaches the |
| 483 | /// end of input or if there was not match. |
| 484 | /// # Example |
| 485 | /// ```rust |
| 486 | /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; |
| 487 | /// use nom::bytes::streaming::take_till1; |
| 488 | /// |
| 489 | /// fn till_colon(s: &str) -> IResult<&str, &str> { |
| 490 | /// take_till1(|c| c == ':')(s) |
| 491 | /// } |
| 492 | /// |
| 493 | /// assert_eq!(till_colon("latin:123"), Ok((":123", "latin"))); |
| 494 | /// assert_eq!(till_colon(":empty matched"), Err(Err::Error(Error::new(":empty matched", ErrorKind::TakeTill1)))); |
| 495 | /// assert_eq!(till_colon("12345"), Err(Err::Incomplete(Needed::new(1)))); |
| 496 | /// assert_eq!(till_colon(""), Err(Err::Incomplete(Needed::new(1)))); |
| 497 | /// ``` |
| 498 | #[allow(clippy::redundant_closure)] |
| 499 | pub fn take_till1<F, I, Error: ParseError<I>>(cond: F) -> impl Parser<I, Output = I, Error = Error> |
| 500 | where |
| 501 | I: Input, |
| 502 | F: Fn(<I as Input>::Item) -> bool, |
| 503 | { |
| 504 | SplitPosition1 { |
| 505 | e: ErrorKind::TakeTill1, |
| 506 | predicate: cond, |
| 507 | error: PhantomData, |
| 508 | } |
| 509 | } |
| 510 | |
| 511 | /// Returns an input slice containing the first N input elements (Input[..N]). |
| 512 | /// |
| 513 | /// # Streaming Specific |
| 514 | /// *Streaming version* if the input has less than N elements, `take` will |
| 515 | /// return a `Err::Incomplete(Needed::new(M))` where M is the number of |
| 516 | /// additional bytes the parser would need to succeed. |
| 517 | /// It is well defined for `&[u8]` as the number of elements is the byte size, |
| 518 | /// but for types like `&str`, we cannot know how many bytes correspond for |
| 519 | /// the next few chars, so the result will be `Err::Incomplete(Needed::Unknown)` |
| 520 | /// |
| 521 | /// # Example |
| 522 | /// ```rust |
| 523 | /// # use nom::{Err, error::ErrorKind, Needed, IResult}; |
| 524 | /// use nom::bytes::streaming::take; |
| 525 | /// |
| 526 | /// fn take6(s: &str) -> IResult<&str, &str> { |
| 527 | /// take(6usize)(s) |
| 528 | /// } |
| 529 | /// |
| 530 | /// assert_eq!(take6("1234567"), Ok(("7", "123456"))); |
| 531 | /// assert_eq!(take6("things"), Ok(("", "things"))); |
| 532 | /// assert_eq!(take6("short"), Err(Err::Incomplete(Needed::Unknown))); |
| 533 | /// ``` |
| 534 | pub fn take<C, I, Error: ParseError<I>>(count: C) -> impl Parser<I, Output = I, Error = Error> |
| 535 | where |
| 536 | I: Input, |
| 537 | C: ToUsize, |
| 538 | { |
| 539 | Take { |
| 540 | length: count.to_usize(), |
| 541 | e: PhantomData, |
| 542 | } |
| 543 | } |
| 544 | |
| 545 | /// Parser implementation for [take] |
| 546 | pub struct Take<E> { |
| 547 | length: usize, |
| 548 | e: PhantomData<E>, |
| 549 | } |
| 550 | |
| 551 | impl<I, Error: ParseError<I>> Parser<I> for Take<Error> |
| 552 | where |
| 553 | I: Input, |
| 554 | { |
| 555 | type Output = I; |
| 556 | type Error = Error; |
| 557 | |
| 558 | fn process<OM: OutputMode>(&mut self, i: I) -> crate::PResult<OM, I, Self::Output, Self::Error> { |
| 559 | match i.slice_index(self.length) { |
| 560 | Err(needed) => { |
| 561 | if OM::Incomplete::is_streaming() { |
| 562 | Err(Err::Incomplete(needed)) |
| 563 | } else { |
| 564 | Err(Err::Error(OM::Error::bind(|| { |
| 565 | let e: ErrorKind = ErrorKind::Eof; |
| 566 | Error::from_error_kind(i, e) |
| 567 | }))) |
| 568 | } |
| 569 | } |
| 570 | Ok(index) => Ok((i.take_from(index), OM::Output::bind(|| i.take(index)))), |
| 571 | } |
| 572 | } |
| 573 | } |
| 574 | |
| 575 | /// Returns the input slice up to the first occurrence of the pattern. |
| 576 | /// |
| 577 | /// It doesn't consume the pattern. |
| 578 | /// |
| 579 | /// # Streaming Specific |
| 580 | /// *Streaming version* will return a `Err::Incomplete(Needed::new(N))` if the input doesn't |
| 581 | /// contain the pattern or if the input is smaller than the pattern. |
| 582 | /// # Example |
| 583 | /// ```rust |
| 584 | /// # use nom::{Err, error::ErrorKind, Needed, IResult}; |
| 585 | /// use nom::bytes::streaming::take_until; |
| 586 | /// |
| 587 | /// fn until_eof(s: &str) -> IResult<&str, &str> { |
| 588 | /// take_until("eof")(s) |
| 589 | /// } |
| 590 | /// |
| 591 | /// assert_eq!(until_eof("hello, worldeof"), Ok(("eof", "hello, world"))); |
| 592 | /// assert_eq!(until_eof("hello, world"), Err(Err::Incomplete(Needed::Unknown))); |
| 593 | /// assert_eq!(until_eof("hello, worldeo"), Err(Err::Incomplete(Needed::Unknown))); |
| 594 | /// assert_eq!(until_eof("1eof2eof"), Ok(("eof2eof", "1"))); |
| 595 | /// ``` |
| 596 | pub fn take_until<T, I, Error: ParseError<I>>(tag: T) -> impl Parser<I, Output = I, Error = Error> |
| 597 | where |
| 598 | I: Input + FindSubstring<T>, |
| 599 | T: Clone, |
| 600 | { |
| 601 | TakeUntil { |
| 602 | tag, |
| 603 | e: PhantomData, |
| 604 | } |
| 605 | } |
| 606 | |
| 607 | /// Parser implementation for [take_until] |
| 608 | pub struct TakeUntil<T, E> { |
| 609 | tag: T, |
| 610 | e: PhantomData<E>, |
| 611 | } |
| 612 | |
| 613 | impl<I, T, Error: ParseError<I>> Parser<I> for TakeUntil<T, Error> |
| 614 | where |
| 615 | I: Input + FindSubstring<T>, |
| 616 | T: Clone, |
| 617 | { |
| 618 | type Output = I; |
| 619 | type Error = Error; |
| 620 | |
| 621 | fn process<OM: OutputMode>(&mut self, i: I) -> crate::PResult<OM, I, Self::Output, Self::Error> { |
| 622 | match i.find_substring(self.tag.clone()) { |
| 623 | None => { |
| 624 | if OM::Incomplete::is_streaming() { |
| 625 | Err(Err::Incomplete(Needed::Unknown)) |
| 626 | } else { |
| 627 | Err(Err::Error(OM::Error::bind(|| { |
| 628 | let e: ErrorKind = ErrorKind::TakeUntil; |
| 629 | Error::from_error_kind(i, e) |
| 630 | }))) |
| 631 | } |
| 632 | } |
| 633 | Some(index) => Ok((i.take_from(index), OM::Output::bind(|| i.take(index)))), |
| 634 | } |
| 635 | } |
| 636 | } |
| 637 | |
| 638 | /// Returns the non empty input slice up to the first occurrence of the pattern. |
| 639 | /// |
| 640 | /// It doesn't consume the pattern. |
| 641 | /// |
| 642 | /// # Streaming Specific |
| 643 | /// *Streaming version* will return a `Err::Incomplete(Needed::new(N))` if the input doesn't |
| 644 | /// contain the pattern or if the input is smaller than the pattern. |
| 645 | /// # Example |
| 646 | /// ```rust |
| 647 | /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; |
| 648 | /// use nom::bytes::streaming::take_until1; |
| 649 | /// |
| 650 | /// fn until_eof(s: &str) -> IResult<&str, &str> { |
| 651 | /// take_until1("eof")(s) |
| 652 | /// } |
| 653 | /// |
| 654 | /// assert_eq!(until_eof("hello, worldeof"), Ok(("eof", "hello, world"))); |
| 655 | /// assert_eq!(until_eof("hello, world"), Err(Err::Incomplete(Needed::Unknown))); |
| 656 | /// assert_eq!(until_eof("hello, worldeo"), Err(Err::Incomplete(Needed::Unknown))); |
| 657 | /// assert_eq!(until_eof("1eof2eof"), Ok(("eof2eof", "1"))); |
| 658 | /// assert_eq!(until_eof("eof"), Err(Err::Error(Error::new("eof", ErrorKind::TakeUntil)))); |
| 659 | /// ``` |
| 660 | pub fn take_until1<T, I, Error: ParseError<I>>(tag: T) -> impl Parser<I, Output = I, Error = Error> |
| 661 | where |
| 662 | I: Input + FindSubstring<T>, |
| 663 | T: Clone, |
| 664 | { |
| 665 | TakeUntil1 { |
| 666 | tag, |
| 667 | e: PhantomData, |
| 668 | } |
| 669 | } |
| 670 | |
| 671 | /// Parser implementation for take_until1 |
| 672 | pub struct TakeUntil1<T, E> { |
| 673 | tag: T, |
| 674 | e: PhantomData<E>, |
| 675 | } |
| 676 | |
| 677 | impl<I, T, Error: ParseError<I>> Parser<I> for TakeUntil1<T, Error> |
| 678 | where |
| 679 | I: Input + FindSubstring<T>, |
| 680 | T: Clone, |
| 681 | { |
| 682 | type Output = I; |
| 683 | type Error = Error; |
| 684 | |
| 685 | fn process<OM: OutputMode>(&mut self, i: I) -> crate::PResult<OM, I, Self::Output, Self::Error> { |
| 686 | match i.find_substring(self.tag.clone()) { |
| 687 | None => { |
| 688 | if OM::Incomplete::is_streaming() { |
| 689 | Err(Err::Incomplete(Needed::Unknown)) |
| 690 | } else { |
| 691 | Err(Err::Error(OM::Error::bind(|| { |
| 692 | let e: ErrorKind = ErrorKind::TakeUntil; |
| 693 | Error::from_error_kind(i, e) |
| 694 | }))) |
| 695 | } |
| 696 | } |
| 697 | Some(0) => Err(Err::Error(OM::Error::bind(|| { |
| 698 | Error::from_error_kind(i, ErrorKind::TakeUntil) |
| 699 | }))), |
| 700 | |
| 701 | Some(index) => Ok((i.take_from(index), OM::Output::bind(|| i.take(index)))), |
| 702 | } |
| 703 | } |
| 704 | } |
| 705 | |
| 706 | /// Matches a byte string with escaped characters. |
| 707 | /// |
| 708 | /// * The first argument matches the normal characters (it must not accept the control character) |
| 709 | /// * The second argument is the control character (like `\` in most languages) |
| 710 | /// * The third argument matches the escaped characters |
| 711 | /// # Example |
| 712 | /// ``` |
| 713 | /// # use nom::{Err, error::ErrorKind, Needed, IResult}; |
| 714 | /// # use nom::character::complete::digit1; |
| 715 | /// use nom::bytes::streaming::escaped; |
| 716 | /// use nom::character::streaming::one_of; |
| 717 | /// |
| 718 | /// fn esc(s: &str) -> IResult<&str, &str> { |
| 719 | /// escaped(digit1, '\\', one_of("\"n\\"))(s) |
| 720 | /// } |
| 721 | /// |
| 722 | /// assert_eq!(esc("123;"), Ok((";", "123"))); |
| 723 | /// assert_eq!(esc("12\\\"34;"), Ok((";", "12\\\"34"))); |
| 724 | /// ``` |
| 725 | /// |
| 726 | pub fn escaped<I, Error, F, G>( |
| 727 | normal: F, |
| 728 | control_char: char, |
| 729 | escapable: G, |
| 730 | ) -> impl Parser<I, Output = I, Error = Error> |
| 731 | where |
| 732 | I: Input + Clone + crate::traits::Offset, |
| 733 | <I as Input>::Item: crate::traits::AsChar, |
| 734 | F: Parser<I, Error = Error>, |
| 735 | G: Parser<I, Error = Error>, |
| 736 | Error: ParseError<I>, |
| 737 | { |
| 738 | Escaped { |
| 739 | normal, |
| 740 | escapable, |
| 741 | control_char, |
| 742 | e: PhantomData, |
| 743 | } |
| 744 | } |
| 745 | |
| 746 | /// Parser implementation for [escaped] |
| 747 | pub struct Escaped<F, G, E> { |
| 748 | normal: F, |
| 749 | escapable: G, |
| 750 | control_char: char, |
| 751 | e: PhantomData<E>, |
| 752 | } |
| 753 | |
| 754 | impl<I, Error: ParseError<I>, F, G> Parser<I> for Escaped<F, G, Error> |
| 755 | where |
| 756 | I: Input + Clone + crate::traits::Offset, |
| 757 | <I as Input>::Item: crate::traits::AsChar, |
| 758 | F: Parser<I, Error = Error>, |
| 759 | G: Parser<I, Error = Error>, |
| 760 | Error: ParseError<I>, |
| 761 | { |
| 762 | type Output = I; |
| 763 | type Error = Error; |
| 764 | |
| 765 | fn process<OM: OutputMode>( |
| 766 | &mut self, |
| 767 | input: I, |
| 768 | ) -> crate::PResult<OM, I, Self::Output, Self::Error> { |
| 769 | let mut i = input.clone(); |
| 770 | |
| 771 | while i.input_len() > 0 { |
| 772 | let current_len = i.input_len(); |
| 773 | |
| 774 | match self |
| 775 | .normal |
| 776 | .process::<OutputM<Check, Check, OM::Incomplete>>(i.clone()) |
| 777 | { |
| 778 | Ok((i2, _)) => { |
| 779 | if i2.input_len() == 0 { |
| 780 | if OM::Incomplete::is_streaming() { |
| 781 | return Err(Err::Incomplete(Needed::Unknown)); |
| 782 | } else { |
| 783 | let index = input.input_len(); |
| 784 | return Ok(( |
| 785 | input.take_from(index), |
| 786 | OM::Output::bind(|| input.take(index)), |
| 787 | )); |
| 788 | } |
| 789 | } else if i2.input_len() == current_len { |
| 790 | let index = input.offset(&i2); |
| 791 | return Ok(( |
| 792 | input.take_from(index), |
| 793 | OM::Output::bind(|| input.take(index)), |
| 794 | )); |
| 795 | } else { |
| 796 | i = i2; |
| 797 | } |
| 798 | } |
| 799 | Err(Err::Error(_)) => { |
| 800 | // unwrap() should be safe here since index < $i.input_len() |
| 801 | if i.iter_elements().next().unwrap().as_char() == self.control_char { |
| 802 | let next = self.control_char.len_utf8(); |
| 803 | if next >= i.input_len() { |
| 804 | if OM::Incomplete::is_streaming() { |
| 805 | return Err(Err::Incomplete(Needed::new(1))); |
| 806 | } else { |
| 807 | return Err(Err::Error(OM::Error::bind(|| { |
| 808 | Error::from_error_kind(input, ErrorKind::Escaped) |
| 809 | }))); |
| 810 | } |
| 811 | } else { |
| 812 | match self |
| 813 | .escapable |
| 814 | .process::<OutputM<Check, OM::Error, OM::Incomplete>>(i.take_from(next)) |
| 815 | { |
| 816 | Ok((i2, _)) => { |
| 817 | if i2.input_len() == 0 { |
| 818 | if OM::Incomplete::is_streaming() { |
| 819 | return Err(Err::Incomplete(Needed::Unknown)); |
| 820 | } else { |
| 821 | let index = input.input_len(); |
| 822 | return Ok(( |
| 823 | input.take_from(index), |
| 824 | OM::Output::bind(|| input.take(index)), |
| 825 | )); |
| 826 | } |
| 827 | } else { |
| 828 | i = i2; |
| 829 | } |
| 830 | } |
| 831 | Err(e) => return Err(e), |
| 832 | } |
| 833 | } |
| 834 | } else { |
| 835 | let index = input.offset(&i); |
| 836 | if index == 0 { |
| 837 | return Err(Err::Error(OM::Error::bind(|| { |
| 838 | Error::from_error_kind(input, ErrorKind::Escaped) |
| 839 | }))); |
| 840 | } else { |
| 841 | return Ok(( |
| 842 | input.take_from(index), |
| 843 | OM::Output::bind(|| input.take(index)), |
| 844 | )); |
| 845 | } |
| 846 | } |
| 847 | } |
| 848 | Err(Err::Failure(e)) => { |
| 849 | return Err(Err::Failure(e)); |
| 850 | } |
| 851 | Err(Err::Incomplete(i)) => { |
| 852 | return Err(Err::Incomplete(i)); |
| 853 | } |
| 854 | } |
| 855 | } |
| 856 | |
| 857 | if OM::Incomplete::is_streaming() { |
| 858 | Err(Err::Incomplete(Needed::Unknown)) |
| 859 | } else { |
| 860 | let index = input.input_len(); |
| 861 | Ok(( |
| 862 | input.take_from(index), |
| 863 | OM::Output::bind(|| input.take(index)), |
| 864 | )) |
| 865 | } |
| 866 | } |
| 867 | } |
| 868 | |
| 869 | /// Matches a byte string with escaped characters. |
| 870 | /// |
| 871 | /// * The first argument matches the normal characters (it must not match the control character) |
| 872 | /// * The second argument is the control character (like `\` in most languages) |
| 873 | /// * The third argument matches the escaped characters and transforms them |
| 874 | /// |
| 875 | /// As an example, the chain `abc\tdef` could be `abc def` (it also consumes the control character) |
| 876 | /// |
| 877 | /// ``` |
| 878 | /// # use nom::{Err, error::ErrorKind, Needed, IResult}; |
| 879 | /// # use std::str::from_utf8; |
| 880 | /// use nom::bytes::streaming::{escaped_transform, tag}; |
| 881 | /// use nom::character::streaming::alpha1; |
| 882 | /// use nom::branch::alt; |
| 883 | /// use nom::combinator::value; |
| 884 | /// |
| 885 | /// fn parser(input: &str) -> IResult<&str, String> { |
| 886 | /// escaped_transform( |
| 887 | /// alpha1, |
| 888 | /// '\\', |
| 889 | /// alt(( |
| 890 | /// value("\\", tag("\\")), |
| 891 | /// value("\"", tag("\"")), |
| 892 | /// value("\n", tag("n")), |
| 893 | /// )) |
| 894 | /// )(input) |
| 895 | /// } |
| 896 | /// |
| 897 | /// assert_eq!(parser("ab\\\"cd\""), Ok(("\"", String::from("ab\"cd")))); |
| 898 | /// ``` |
| 899 | #[cfg(feature = "alloc")] |
| 900 | #[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] |
| 901 | pub fn escaped_transform<I, Error, F, G, ExtendItem, Output>( |
| 902 | normal: F, |
| 903 | control_char: char, |
| 904 | transform: G, |
| 905 | ) -> impl Parser<I, Output = Output, Error = Error> |
| 906 | where |
| 907 | I: Clone + crate::traits::Offset + Input, |
| 908 | I: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>, |
| 909 | <F as Parser<I>>::Output: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>, |
| 910 | <G as Parser<I>>::Output: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>, |
| 911 | <I as Input>::Item: crate::traits::AsChar, |
| 912 | F: Parser<I, Error = Error>, |
| 913 | G: Parser<I, Error = Error>, |
| 914 | Error: ParseError<I>, |
| 915 | { |
| 916 | EscapedTransform { |
| 917 | normal, |
| 918 | control_char, |
| 919 | transform, |
| 920 | e: PhantomData, |
| 921 | extend: PhantomData, |
| 922 | o: PhantomData, |
| 923 | } |
| 924 | } |
| 925 | |
| 926 | /// Parser implementation for [escaped_transform] |
| 927 | pub struct EscapedTransform<F, G, E, ExtendItem, Output> { |
| 928 | normal: F, |
| 929 | transform: G, |
| 930 | control_char: char, |
| 931 | e: PhantomData<E>, |
| 932 | extend: PhantomData<ExtendItem>, |
| 933 | o: PhantomData<Output>, |
| 934 | } |
| 935 | |
| 936 | impl<I, Error: ParseError<I>, F, G, ExtendItem, Output> Parser<I> |
| 937 | for EscapedTransform<F, G, Error, ExtendItem, Output> |
| 938 | where |
| 939 | I: Clone + crate::traits::Offset + Input, |
| 940 | I: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>, |
| 941 | <F as Parser<I>>::Output: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>, |
| 942 | <G as Parser<I>>::Output: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>, |
| 943 | <I as Input>::Item: crate::traits::AsChar, |
| 944 | F: Parser<I, Error = Error>, |
| 945 | G: Parser<I, Error = Error>, |
| 946 | Error: ParseError<I>, |
| 947 | { |
| 948 | type Output = Output; |
| 949 | type Error = Error; |
| 950 | |
| 951 | fn process<OM: OutputMode>( |
| 952 | &mut self, |
| 953 | input: I, |
| 954 | ) -> crate::PResult<OM, I, Self::Output, Self::Error> { |
| 955 | let mut index = 0; |
| 956 | let mut res = OM::Output::bind(|| input.new_builder()); |
| 957 | |
| 958 | while index < input.input_len() { |
| 959 | let current_len = input.input_len(); |
| 960 | let remainder = input.take_from(index); |
| 961 | match self.normal.process::<OM>(remainder.clone()) { |
| 962 | Ok((i2, o)) => { |
| 963 | res = OM::Output::combine(o, res, |o, mut res| { |
| 964 | o.extend_into(&mut res); |
| 965 | res |
| 966 | }); |
| 967 | if i2.input_len() == 0 { |
| 968 | if OM::Incomplete::is_streaming() { |
| 969 | return Err(Err::Incomplete(Needed::Unknown)); |
| 970 | } else { |
| 971 | let index = input.input_len(); |
| 972 | return Ok((input.take_from(index), res)); |
| 973 | } |
| 974 | } else if i2.input_len() == current_len { |
| 975 | return Ok((remainder, res)); |
| 976 | } else { |
| 977 | index = input.offset(&i2); |
| 978 | } |
| 979 | } |
| 980 | Err(Err::Error(_)) => { |
| 981 | // unwrap() should be safe here since index < $i.input_len() |
| 982 | if remainder.iter_elements().next().unwrap().as_char() == self.control_char { |
| 983 | let next = index + self.control_char.len_utf8(); |
| 984 | let input_len = input.input_len(); |
| 985 | |
| 986 | if next >= input_len { |
| 987 | if OM::Incomplete::is_streaming() { |
| 988 | return Err(Err::Incomplete(Needed::Unknown)); |
| 989 | } else { |
| 990 | return Err(Err::Error(OM::Error::bind(|| { |
| 991 | Error::from_error_kind(remainder, ErrorKind::EscapedTransform) |
| 992 | }))); |
| 993 | } |
| 994 | } else { |
| 995 | match self.transform.process::<OM>(input.take_from(next)) { |
| 996 | Ok((i2, o)) => { |
| 997 | res = OM::Output::combine(o, res, |o, mut res| { |
| 998 | o.extend_into(&mut res); |
| 999 | res |
| 1000 | }); |
| 1001 | if i2.input_len() == 0 { |
| 1002 | if OM::Incomplete::is_streaming() { |
| 1003 | return Err(Err::Incomplete(Needed::Unknown)); |
| 1004 | } else { |
| 1005 | return Ok((input.take_from(input.input_len()), res)); |
| 1006 | } |
| 1007 | } else { |
| 1008 | index = input.offset(&i2); |
| 1009 | } |
| 1010 | } |
| 1011 | Err(Err::Error(e)) => return Err(Err::Error(e)), |
| 1012 | Err(Err::Failure(e)) => { |
| 1013 | return Err(Err::Failure(e)); |
| 1014 | } |
| 1015 | Err(Err::Incomplete(i)) => { |
| 1016 | return Err(Err::Incomplete(i)); |
| 1017 | } |
| 1018 | } |
| 1019 | } |
| 1020 | } else { |
| 1021 | if index == 0 { |
| 1022 | return Err(Err::Error(OM::Error::bind(|| { |
| 1023 | Error::from_error_kind(remainder, ErrorKind::EscapedTransform) |
| 1024 | }))); |
| 1025 | } |
| 1026 | return Ok((remainder, res)); |
| 1027 | } |
| 1028 | } |
| 1029 | Err(Err::Failure(e)) => { |
| 1030 | return Err(Err::Failure(e)); |
| 1031 | } |
| 1032 | Err(Err::Incomplete(i)) => { |
| 1033 | return Err(Err::Incomplete(i)); |
| 1034 | } |
| 1035 | } |
| 1036 | } |
| 1037 | |
| 1038 | if OM::Incomplete::is_streaming() { |
| 1039 | Err(Err::Incomplete(Needed::Unknown)) |
| 1040 | } else { |
| 1041 | Ok((input.take_from(index), res)) |
| 1042 | } |
| 1043 | } |
| 1044 | } |