mirror of
				https://github.com/ocaml-multicore/eio.git
				synced 2025-10-31 00:03:11 -04:00 
			
		
		
		
	Add Buf_read.parse_exn
This commit is contained in:
		
							parent
							
								
									b9a608562d
								
							
						
					
					
						commit
						3b4abcc79c
					
				| @ -278,6 +278,11 @@ let parse ?initial_size ~max_size p flow = | |||||||
|   let buf = of_flow flow ?initial_size ~max_size in |   let buf = of_flow flow ?initial_size ~max_size in | ||||||
|   format_errors (p <* end_of_input) buf |   format_errors (p <* end_of_input) buf | ||||||
| 
 | 
 | ||||||
|  | let parse_exn ?initial_size ~max_size p flow = | ||||||
|  |   match parse ?initial_size ~max_size p flow with | ||||||
|  |   | Ok x -> x | ||||||
|  |   | Error (`Msg m) -> failwith m | ||||||
|  | 
 | ||||||
| [@@inline never] | [@@inline never] | ||||||
| let bad_offset ~expected actual = | let bad_offset ~expected actual = | ||||||
|   Fmt.invalid_arg "Sequence is stale (expected to be used at offset %d, but stream is now at %d)" |   Fmt.invalid_arg "Sequence is stale (expected to be used at offset %d, but stream is now at %d)" | ||||||
|  | |||||||
| @ -628,6 +628,13 @@ module Buf_read : sig | |||||||
| 
 | 
 | ||||||
|       @param initial_size see {!of_flow}. *) |       @param initial_size see {!of_flow}. *) | ||||||
| 
 | 
 | ||||||
|  |   val parse_exn : ?initial_size:int -> max_size:int -> 'a parser -> #Flow.source -> 'a | ||||||
|  |   (** [parse_exn] wraps {!parse}, but raises [Failure msg] if that returns [Error (`Msg msg)]. | ||||||
|  | 
 | ||||||
|  |       Catching exceptions with [parse] and then raising them might seem pointless, | ||||||
|  |       but this has the effect of turning e.g. an [End_of_file] exception into a [Failure] | ||||||
|  |       with a more user-friendly message. *) | ||||||
|  | 
 | ||||||
|   val of_flow : ?initial_size:int -> max_size:int -> #Flow.source -> t |   val of_flow : ?initial_size:int -> max_size:int -> #Flow.source -> t | ||||||
|   (** [of_flow ~max_size flow] is a buffered reader backed by [flow]. |   (** [of_flow ~max_size flow] is a buffered reader backed by [flow]. | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -51,6 +51,11 @@ let test ?(max_size=10) input p = | |||||||
|   next := input; |   next := input; | ||||||
|   let i = R.of_flow mock_flow ~max_size in |   let i = R.of_flow mock_flow ~max_size in | ||||||
|   p i |   p i | ||||||
|  | 
 | ||||||
|  | let parse_exn p flow ~max_size = | ||||||
|  |   match R.parse_exn p flow ~max_size with | ||||||
|  |   | x -> traceln "Ok: %S" x | ||||||
|  |   | exception Failure msg -> traceln "Failure: %s" msg | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -511,3 +516,51 @@ Invalid_argument | |||||||
|  "Sequence is stale (expected to be used at offset 4, but stream is now at 8)". |  "Sequence is stale (expected to be used at offset 4, but stream is now at 8)". | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | ## Convenience wrapper | ||||||
|  | 
 | ||||||
|  | `parse` turns parser errors into friendly messages: | ||||||
|  | 
 | ||||||
|  | ```ocaml | ||||||
|  | # R.(parse (string "FROM:" *> take_all)) (Eio.Flow.string_source "FROM:A") ~max_size:5;; | ||||||
|  | - : (string, [> `Msg of string ]) result = Ok "A" | ||||||
|  | 
 | ||||||
|  | # R.(parse (string "FROM:" *> take_all)) (Eio.Flow.string_source "TO:B") ~max_size:5;; | ||||||
|  | - : (string, [> `Msg of string ]) result = | ||||||
|  | Error (`Msg "Expected \"FROM:\" but got \"TO:B\" (at offset 0)") | ||||||
|  | 
 | ||||||
|  | # R.(parse (string "FROM:" *> take_all)) (Eio.Flow.string_source "FROM:ABCDE") ~max_size:5;; | ||||||
|  | - : (string, [> `Msg of string ]) result = | ||||||
|  | Error (`Msg "Buffer size limit exceeded when reading at offset 5") | ||||||
|  | 
 | ||||||
|  | # R.(parse (string "END")) (Eio.Flow.string_source "ENDING") ~max_size:5;; | ||||||
|  | - : (unit, [> `Msg of string ]) result = | ||||||
|  | Error (`Msg "Unexpected data after parsing (at offset 3)") | ||||||
|  | 
 | ||||||
|  | # R.(parse (string "END")) (Eio.Flow.string_source "E") ~max_size:5;; | ||||||
|  | - : (unit, [> `Msg of string ]) result = | ||||||
|  | Error (`Msg "Unexpected end-of-file at offset 1") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | `parse_exn` is similar, but raises (we then catch it and print it nicely): | ||||||
|  | 
 | ||||||
|  | ```ocaml | ||||||
|  | # parse_exn R.(string "FROM:" *> take_all) (Eio.Flow.string_source "FROM:A") ~max_size:5;; | ||||||
|  | +Ok: "A" | ||||||
|  | - : unit = () | ||||||
|  | 
 | ||||||
|  | # parse_exn R.(string "FROM:" *> take_all) (Eio.Flow.string_source "TO:B") ~max_size:5;; | ||||||
|  | +Failure: Expected "FROM:" but got "TO:B" (at offset 0) | ||||||
|  | - : unit = () | ||||||
|  | 
 | ||||||
|  | # parse_exn R.(string "FROM:" *> take_all) (Eio.Flow.string_source "FROM:ABCDE") ~max_size:5;; | ||||||
|  | +Failure: Buffer size limit exceeded when reading at offset 5 | ||||||
|  | - : unit = () | ||||||
|  | 
 | ||||||
|  | # parse_exn R.(take 3) (Eio.Flow.string_source "ENDING") ~max_size:5;; | ||||||
|  | +Failure: Unexpected data after parsing (at offset 3) | ||||||
|  | - : unit = () | ||||||
|  | 
 | ||||||
|  | # parse_exn R.(take 3) (Eio.Flow.string_source "E") ~max_size:5;; | ||||||
|  | +Failure: Unexpected end-of-file at offset 1 | ||||||
|  | - : unit = () | ||||||
|  | ``` | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user