1 use crate::{ 2 error::{ParseError, ParseResult, StreamError}, 3 lib::fmt, 4 stream::{ 5 IteratorStream, Positioned, RangeStreamOnce, ResetStream, SliceStream, StreamErrorFor, 6 StreamOnce, 7 }, 8 }; 9 10 #[cfg(feature = "std")] 11 use crate::stream::read; 12 13 /// Trait for tracking the current position of a `Stream`. 14 pub trait Positioner<Item> { 15 /// The type which keeps track of the position 16 type Position: Clone + Ord; 17 18 type Checkpoint: Clone; 19 20 /// Returns the current position position(&self) -> Self::Position21 fn position(&self) -> Self::Position; 22 /// Updates the position given that `token` has been taken from the stream update(&mut self, token: &Item)23 fn update(&mut self, token: &Item); 24 checkpoint(&self) -> Self::Checkpoint25 fn checkpoint(&self) -> Self::Checkpoint; reset(&mut self, checkpoint: Self::Checkpoint)26 fn reset(&mut self, checkpoint: Self::Checkpoint); 27 } 28 29 /// Trait for tracking the current position of a `RangeStream`. 30 pub trait RangePositioner<Item, Range>: Positioner<Item> { 31 /// Updates the position given that `range` has been taken from the stream update_range(&mut self, range: &Range)32 fn update_range(&mut self, range: &Range); 33 } 34 35 /// Defines a default `Positioner` type for a particular `Stream` type. 36 pub trait DefaultPositioned { 37 type Positioner: Default; 38 } 39 40 impl<'a> DefaultPositioned for &'a str { 41 type Positioner = SourcePosition; 42 } 43 44 impl<'a, T> DefaultPositioned for &'a [T] { 45 type Positioner = IndexPositioner; 46 } 47 48 impl<'a, T> DefaultPositioned for SliceStream<'a, T> { 49 type Positioner = IndexPositioner; 50 } 51 52 impl<T> DefaultPositioned for IteratorStream<T> { 53 type Positioner = IndexPositioner; 54 } 55 56 #[cfg(feature = "std")] 57 impl<R> DefaultPositioned for read::Stream<R> { 58 type Positioner = IndexPositioner; 59 } 60 61 /// The `Stream<Input>` struct maintains the current position in the stream `Input` using 62 /// the `Positioner` trait to track the position. 63 /// 64 /// ``` 65 /// # #![cfg(feature = "std")] 66 /// # extern crate combine; 67 /// # use combine::*; 68 /// # use combine::stream::easy; 69 /// # use combine::stream::position; 70 /// # fn main() { 71 /// let result = token(b'9') 72 /// .message("Not a nine") 73 /// .easy_parse(position::Stream::new(&b"8"[..])); 74 /// assert_eq!(result, Err(easy::Errors { 75 /// position: 0, 76 /// errors: vec![ 77 /// easy::Error::Unexpected(b'8'.into()), 78 /// easy::Error::Expected(b'9'.into()), 79 /// easy::Error::Message("Not a nine".into()) 80 /// ] 81 /// })); 82 /// # } 83 /// ``` 84 #[derive(Clone, Debug, PartialEq)] 85 pub struct Stream<Input, X> { 86 /// The input stream used when items are requested 87 pub input: Input, 88 /// The positioner used to update the current position 89 pub positioner: X, 90 } 91 92 impl<Input, X> Stream<Input, X> 93 where 94 Input: StreamOnce, 95 X: Positioner<Input::Token>, 96 { 97 /// Creates a new `Stream<Input, X>` from an input stream and a positioner. with_positioner(input: Input, positioner: X) -> Stream<Input, X>98 pub fn with_positioner(input: Input, positioner: X) -> Stream<Input, X> { 99 Stream { input, positioner } 100 } 101 } 102 103 impl<Input> Stream<Input, Input::Positioner> 104 where 105 Input: StreamOnce + DefaultPositioned, 106 Input::Positioner: Positioner<Input::Token>, 107 { 108 /// Creates a new `Stream<Input, X>` from an input stream and its default positioner. new(input: Input) -> Stream<Input, Input::Positioner>109 pub fn new(input: Input) -> Stream<Input, Input::Positioner> { 110 Stream::with_positioner(input, Input::Positioner::default()) 111 } 112 } 113 114 impl<Input, X, S> Positioned for Stream<Input, X> 115 where 116 Input: StreamOnce, 117 X: Positioner<Input::Token>, 118 S: StreamError<Input::Token, Input::Range>, 119 Input::Error: ParseError<Input::Token, Input::Range, X::Position, StreamError = S>, 120 Input::Error: ParseError<Input::Token, Input::Range, Input::Position, StreamError = S>, 121 { 122 #[inline] position(&self) -> Self::Position123 fn position(&self) -> Self::Position { 124 self.positioner.position() 125 } 126 } 127 128 impl<Input, X, S> StreamOnce for Stream<Input, X> 129 where 130 Input: StreamOnce, 131 X: Positioner<Input::Token>, 132 S: StreamError<Input::Token, Input::Range>, 133 Input::Error: ParseError<Input::Token, Input::Range, X::Position, StreamError = S>, 134 Input::Error: ParseError<Input::Token, Input::Range, Input::Position, StreamError = S>, 135 { 136 type Token = Input::Token; 137 type Range = Input::Range; 138 type Position = X::Position; 139 type Error = Input::Error; 140 141 #[inline] uncons(&mut self) -> Result<Input::Token, StreamErrorFor<Self>>142 fn uncons(&mut self) -> Result<Input::Token, StreamErrorFor<Self>> { 143 self.input.uncons().map(|c| { 144 self.positioner.update(&c); 145 c 146 }) 147 } 148 is_partial(&self) -> bool149 fn is_partial(&self) -> bool { 150 self.input.is_partial() 151 } 152 } 153 154 impl<Item, T> Positioner<Item> for &'_ mut T 155 where 156 Item: Clone, 157 T: ?Sized + Positioner<Item>, 158 { 159 type Position = T::Position; 160 type Checkpoint = T::Checkpoint; 161 162 #[inline] position(&self) -> T::Position163 fn position(&self) -> T::Position { 164 (**self).position() 165 } 166 167 #[inline] update(&mut self, item: &Item)168 fn update(&mut self, item: &Item) { 169 (**self).update(item) 170 } 171 172 #[inline] checkpoint(&self) -> Self::Checkpoint173 fn checkpoint(&self) -> Self::Checkpoint { 174 (**self).checkpoint() 175 } 176 177 #[inline] reset(&mut self, checkpoint: Self::Checkpoint)178 fn reset(&mut self, checkpoint: Self::Checkpoint) { 179 (**self).reset(checkpoint) 180 } 181 } 182 183 impl<Item, Range, T> RangePositioner<Item, Range> for &'_ mut T 184 where 185 Item: Clone, 186 Range: Clone + crate::stream::Range, 187 T: ?Sized + RangePositioner<Item, Range>, 188 { update_range(&mut self, range: &Range)189 fn update_range(&mut self, range: &Range) { 190 (**self).update_range(range); 191 } 192 } 193 194 /// The `IndexPositioner<Item, Range>` struct maintains the current index into the stream `Input`. The 195 /// initial index is index 0. Each `Item` committed increments the index by 1; each `range` committed 196 /// increments the position by `range.len()`. 197 #[derive(Clone, Debug, Default, PartialEq)] 198 pub struct IndexPositioner(usize); 199 200 impl<Item> Positioner<Item> for IndexPositioner 201 where 202 Item: Clone, 203 { 204 type Position = usize; 205 type Checkpoint = Self; 206 207 #[inline] position(&self) -> usize208 fn position(&self) -> usize { 209 self.0 210 } 211 212 #[inline] update(&mut self, _item: &Item)213 fn update(&mut self, _item: &Item) { 214 self.0 += 1 215 } 216 217 #[inline] checkpoint(&self) -> Self::Checkpoint218 fn checkpoint(&self) -> Self::Checkpoint { 219 self.clone() 220 } 221 222 #[inline] reset(&mut self, checkpoint: Self::Checkpoint)223 fn reset(&mut self, checkpoint: Self::Checkpoint) { 224 *self = checkpoint; 225 } 226 } 227 228 impl IndexPositioner { new() -> IndexPositioner229 pub fn new() -> IndexPositioner { 230 IndexPositioner::new_with_position(0) 231 } 232 new_with_position(position: usize) -> IndexPositioner233 pub fn new_with_position(position: usize) -> IndexPositioner { 234 IndexPositioner(position) 235 } 236 } 237 238 impl<Item, Range> RangePositioner<Item, Range> for IndexPositioner 239 where 240 Item: Clone, 241 Range: Clone + crate::stream::Range, 242 { update_range(&mut self, range: &Range)243 fn update_range(&mut self, range: &Range) { 244 self.0 += range.len() 245 } 246 } 247 248 /// Struct which represents a position in a source file. 249 #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] 250 pub struct SourcePosition { 251 /// Current line of the input 252 pub line: i32, 253 /// Current column of the input 254 pub column: i32, 255 } 256 257 impl Default for SourcePosition { default() -> Self258 fn default() -> Self { 259 SourcePosition { line: 1, column: 1 } 260 } 261 } 262 263 impl fmt::Display for SourcePosition { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result264 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 265 write!(f, "line: {}, column: {}", self.line, self.column) 266 } 267 } 268 269 impl SourcePosition { new() -> Self270 pub fn new() -> Self { 271 SourcePosition::default() 272 } 273 } 274 275 impl Positioner<char> for SourcePosition { 276 type Position = SourcePosition; 277 type Checkpoint = Self; 278 279 #[inline] position(&self) -> SourcePosition280 fn position(&self) -> SourcePosition { 281 *self 282 } 283 284 #[inline] update(&mut self, token: &char)285 fn update(&mut self, token: &char) { 286 self.column += 1; 287 if *token == '\n' { 288 self.column = 1; 289 self.line += 1; 290 } 291 } 292 293 #[inline] checkpoint(&self) -> Self::Checkpoint294 fn checkpoint(&self) -> Self::Checkpoint { 295 *self 296 } 297 298 #[inline] reset(&mut self, checkpoint: Self::Checkpoint)299 fn reset(&mut self, checkpoint: Self::Checkpoint) { 300 *self = checkpoint; 301 } 302 } 303 304 impl Positioner<u8> for SourcePosition { 305 type Position = SourcePosition; 306 type Checkpoint = Self; 307 308 #[inline] position(&self) -> SourcePosition309 fn position(&self) -> SourcePosition { 310 *self 311 } 312 313 #[inline] update(&mut self, token: &u8)314 fn update(&mut self, token: &u8) { 315 self.column += 1; 316 if *token == b'\n' { 317 self.column = 1; 318 self.line += 1; 319 } 320 } 321 322 #[inline] checkpoint(&self) -> Self::Checkpoint323 fn checkpoint(&self) -> Self::Checkpoint { 324 *self 325 } 326 327 #[inline] reset(&mut self, checkpoint: Self::Checkpoint)328 fn reset(&mut self, checkpoint: Self::Checkpoint) { 329 *self = checkpoint; 330 } 331 } 332 333 impl<'a> RangePositioner<char, &'a str> for SourcePosition { update_range(&mut self, range: &&'a str)334 fn update_range(&mut self, range: &&'a str) { 335 for c in range.chars() { 336 self.update(&c); 337 } 338 } 339 } 340 341 impl<Input, X, S> RangeStreamOnce for Stream<Input, X> 342 where 343 Input: RangeStreamOnce, 344 X: RangePositioner<Input::Token, Input::Range>, 345 S: StreamError<Input::Token, Input::Range>, 346 Input::Error: ParseError<Input::Token, Input::Range, X::Position, StreamError = S>, 347 Input::Error: ParseError<Input::Token, Input::Range, Input::Position, StreamError = S>, 348 Input::Position: Clone + Ord, 349 { 350 #[inline] uncons_range(&mut self, size: usize) -> Result<Input::Range, StreamErrorFor<Self>>351 fn uncons_range(&mut self, size: usize) -> Result<Input::Range, StreamErrorFor<Self>> { 352 self.input.uncons_range(size).map(|range| { 353 self.positioner.update_range(&range); 354 range 355 }) 356 } 357 358 #[inline] uncons_while<F>(&mut self, mut predicate: F) -> Result<Input::Range, StreamErrorFor<Self>> where F: FnMut(Input::Token) -> bool,359 fn uncons_while<F>(&mut self, mut predicate: F) -> Result<Input::Range, StreamErrorFor<Self>> 360 where 361 F: FnMut(Input::Token) -> bool, 362 { 363 let positioner = &mut self.positioner; 364 self.input.uncons_while(|t| { 365 if predicate(t.clone()) { 366 positioner.update(&t); 367 true 368 } else { 369 false 370 } 371 }) 372 } 373 374 #[inline] uncons_while1<F>( &mut self, mut predicate: F, ) -> ParseResult<Self::Range, StreamErrorFor<Self>> where F: FnMut(Self::Token) -> bool,375 fn uncons_while1<F>( 376 &mut self, 377 mut predicate: F, 378 ) -> ParseResult<Self::Range, StreamErrorFor<Self>> 379 where 380 F: FnMut(Self::Token) -> bool, 381 { 382 let positioner = &mut self.positioner; 383 self.input.uncons_while1(|t| { 384 if predicate(t.clone()) { 385 positioner.update(&t); 386 true 387 } else { 388 false 389 } 390 }) 391 } 392 393 #[inline] distance(&self, end: &Self::Checkpoint) -> usize394 fn distance(&self, end: &Self::Checkpoint) -> usize { 395 self.input.distance(&end.input) 396 } 397 range(&self) -> Self::Range398 fn range(&self) -> Self::Range { 399 self.input.range() 400 } 401 } 402 403 impl<Input, X, S> ResetStream for Stream<Input, X> 404 where 405 Input: ResetStream, 406 X: Positioner<Input::Token>, 407 S: StreamError<Input::Token, Input::Range>, 408 Input::Error: ParseError<Input::Token, Input::Range, X::Position, StreamError = S>, 409 Input::Error: ParseError<Input::Token, Input::Range, Input::Position, StreamError = S>, 410 { 411 type Checkpoint = Stream<Input::Checkpoint, X::Checkpoint>; checkpoint(&self) -> Self::Checkpoint412 fn checkpoint(&self) -> Self::Checkpoint { 413 Stream { 414 input: self.input.checkpoint(), 415 positioner: self.positioner.checkpoint(), 416 } 417 } reset(&mut self, checkpoint: Self::Checkpoint) -> Result<(), Self::Error>418 fn reset(&mut self, checkpoint: Self::Checkpoint) -> Result<(), Self::Error> { 419 self.input.reset(checkpoint.input)?; 420 self.positioner.reset(checkpoint.positioner); 421 Ok(()) 422 } 423 } 424 425 #[cfg(all(feature = "std", test))] 426 mod tests { 427 428 use crate::Parser; 429 430 use super::*; 431 432 #[test] test_positioner()433 fn test_positioner() { 434 let input = ["a".to_string(), "b".to_string()]; 435 let mut parser = crate::any(); 436 let result = parser.parse(Stream::new(&input[..])); 437 assert_eq!( 438 result, 439 Ok(( 440 "a".to_string(), 441 Stream::with_positioner( 442 &["b".to_string()][..], 443 IndexPositioner::new_with_position(1) 444 ) 445 )) 446 ); 447 } 448 449 #[test] test_range_positioner()450 fn test_range_positioner() { 451 let input = ["a".to_string(), "b".to_string(), "c".to_string()]; 452 let mut parser = crate::parser::range::take(2); 453 let result = parser.parse(Stream::new(&input[..])); 454 assert_eq!( 455 result, 456 Ok(( 457 &["a".to_string(), "b".to_string()][..], 458 Stream::with_positioner( 459 &["c".to_string()][..], 460 IndexPositioner::new_with_position(2) 461 ) 462 )) 463 ); 464 } 465 } 466