Repository: rust-bakery/nom (language: rust)

Issue:
Err::to_owned uses old tuple instead of new error::Error type
- Rust version : `rustc 1.48.0-nightly (623fb90b5 2020-09-26)`
- nom version : `6.0.1`
- nom compilation features used: `[]`

The `Err::to_owned` uses the old IResult definition. Both the implementations for `&str` and `&[u8]` should probably be rewritten for the updated IResult.

Current version:
https://github.com/Geal/nom/blob/bd1adeb8cee593dfedb971df4f5aa26b8a011578/src/internal.rs#L153-L171



Discussion / hints:
I'm running into issues with this.

I could put together a pr, assuming it's just implementing a generic `Clone` & `ToOwned` on `nom::error::Error` if that would be useful.
@ArenM are you working on it? I am having issues as well, and I'd like to open a PR to fix it :)
I didn't end up making a fix for this. As far as I can remember `ToOwned` has a generic implemation that calls clone, and it is actually correct for clone to only clone the outermost object, so implementing this in a way that looks and feels nice is a bit of a challenge. As a jumping off point this code should work pretty well, except that it will break if `nom::error::VerboseError` is used instead of `nom::error::Error`:
```rust
some_parser(input).map_err(|e| {
     e.map(|e2| nom::error::Error {
         input: e2.input.to_owned(),
         code: e2.code,
    })
});
```

Fix patch:
diff --git a/src/internal.rs b/src/internal.rs
index fd683c00b..fa7e589ce 100644
--- a/src/internal.rs
+++ b/src/internal.rs
@@ -150,6 +150,26 @@ impl<T> Err<(T, ErrorKind)> {
   }
 }
 
+impl<T> Err<error::Error<T>> {
+  /// Maps `Err<error::Error<T>>` to `Err<error::Error<U>>` with the given `F: T -> U`
+  pub fn map_input<U, F>(self, f: F) -> Err<error::Error<U>>
+  where
+    F: FnOnce(T) -> U,
+  {
+    match self {
+      Err::Incomplete(n) => Err::Incomplete(n),
+      Err::Failure(error::Error { input, code }) => Err::Failure(error::Error {
+        input: f(input),
+        code,
+      }),
+      Err::Error(error::Error { input, code }) => Err::Error(error::Error {
+        input: f(input),
+        code,
+      }),
+    }
+  }
+}
+
 #[cfg(feature = "alloc")]
 use crate::lib::std::{borrow::ToOwned, string::String, vec::Vec};
 #[cfg(feature = "alloc")]
@@ -163,13 +183,31 @@ impl Err<(&[u8], ErrorKind)> {
 
 #[cfg(feature = "alloc")]
 impl Err<(&str, ErrorKind)> {
-  /// Automatically converts between errors if the underlying type supports it
+  /// Obtaining ownership
   #[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))]
   pub fn to_owned(self) -> Err<(String, ErrorKind)> {
     self.map_input(ToOwned::to_owned)
   }
 }
 
+#[cfg(feature = "alloc")]
+impl Err<error::Error<&[u8]>> {
+  /// Obtaining ownership
+  #[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))]
+  pub fn to_owned(self) -> Err<error::Error<Vec<u8>>> {
+    self.map_input(ToOwned::to_owned)
+  }
+}
+
+#[cfg(feature = "alloc")]
+impl Err<error::Error<&str>> {
+  /// Obtaining ownership
+  #[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))]
+  pub fn to_owned(self) -> Err<error::Error<String>> {
+    self.map_input(ToOwned::to_owned)
+  }
+}
+
 impl<E: Eq> Eq for Err<E> {}
 
 impl<E> fmt::Display for Err<E>


Test patch: