@@ -24,7 +24,7 @@ instance : ToString DecodeError where
2424inductive DecodeResult (α) where
2525 | success (x : α) (k : Decoder)
2626 | error (err : DecodeError) (cur : Decoder)
27- | pending (fn : ByteArray → DecodeResult α)
27+ | pending (fn : Option ByteArray → DecodeResult α)
2828deriving Inhabited
2929
3030@[always_inline]
@@ -51,6 +51,7 @@ def DecodeResult.toExceptString : DecodeResult α → Except String α
5151@[expose]
5252def Get (α : Type ) : Type := Decoder → (DecodeResult α)
5353
54+ /-- The bytes in the current inner buffer, **not** considering pending input. -/
5455@[always_inline]
5556def remaining : Get Nat := fun d => DecodeResult.success (d.data.size - d.offset) d
5657
@@ -60,6 +61,15 @@ def DecodeResult.feed {α} (bytes : ByteArray) : DecodeResult α → DecodeResul
6061 | .error err k => .error err (k.append bytes)
6162 | .pending fn => fn bytes
6263
64+ /--
65+ Immediately terminate the pending state.
66+ This is especially useful for terminating something like `optional (pending x)`. -/
67+ @[always_inline]
68+ def DecodeResult.terminate {α} : DecodeResult α → DecodeResult α
69+ | .success x k => .success x k
70+ | .error err k => .error err k
71+ | .pending fn => fn none
72+
6373@[always_inline]
6474instance : Monad Get where
6575 pure x := fun d => DecodeResult.success x d
@@ -191,12 +201,15 @@ Catch any `DecodeError.eoi` and recover to a pending state rather than exit with
191201* ensure that `x` terminates when enough bytes are fed,
192202* or define your own pending function to cache intermediate result as much as possible.
193203 -/
194- @ [specialize, always_inline ]
204+ @[specialize]
195205partial def pending (x : Get α) : Get α := do
196206 try x
197207 catch err =>
198208 match err with
199- | .eoi => fun d => .pending fun bytes => pending x (d.append bytes)
209+ | .eoi => fun d => .pending fun bytes? =>
210+ match bytes? with
211+ | none => DecodeResult.mkEOI d
212+ | some bytes => pending x (d.append bytes)
200213 | e => throw e
201214
202215namespace Primitive
0 commit comments