I am not sure if this is a docopt issue, or an issue with serde. Please hear me out, and let me know if I should file this under docopt instead.
Consider the following example:
#[macro_use]
extern crate serde_derive;
extern crate docopt;
use docopt::Docopt;
const USAGE: &'static str = "
Simple borrowing
Usage:
borrow <name>
Options:
-h --help Show this screen.
";
#[derive(Debug, Deserialize)]
struct Args<'a> {
arg_name: &'a str
}
fn main() {
let args: Args = Docopt::new(USAGE)
.and_then(|d| d.deserialize())
.unwrap_or_else(|e| e.exit());
println!("{:?}", args);
}
When I run cargo run test
, I get a weird error invalid type: string "testing", expected a borrowed string
. The error message was really confusing, and I thought it was because of incorrect usage on my part.
Digging around the source code, it seems like the deserializer for docopt just does not support deserializing borrowed string. (Deserializer::deserialize_str
function always calls Visitor::visit_str
.)
Would this be a case where the error message from serde is confusing, or the deserializer is not implemented correctly?
Looks like a docopt bug. The signature of Docopt::deserialize
should be:
- fn deserialize<'a, 'de: 'a, D>(&'a self) -> Result<D, Error>
- where D: Deserialize<'de>;
+ fn deserialize<D>(&self) -> Result<D, Error>
+ where D: DeserializeOwned;
I've submitted a PR to docopt. I'll close this issue since this is not a problem with serde.
@dtolnay The original issue doesn't seem to be addressed though? Just got also beaten by this error message, and if I wouldn't find this particular issue, could spend much more time trying to find a mistake in my own code.
Basically, I was trying to parse a bunch of JSON-based tests, and in the middle of parsing was getting
invalid type: string "�", expected a borrowed string"
It took a while to realize the reason for this. Indeed, serde_json can't return a slice if a string contained escaped characters, as in that case it must create a heap-allocated copy to unescape them.
Would it make sense to improve error message to clarify this?
Or maybe, deserializer could somehow return references to temporarily allocated strings to make these cases transparent to consumer (not sure if that's possible though)?
Or maybe better to prohibit deserializing slices altogether in deserializers that might need unescaping, for consistency?
In any case, it would be nice to clarify this situation.
Most helpful comment
@dtolnay The original issue doesn't seem to be addressed though? Just got also beaten by this error message, and if I wouldn't find this particular issue, could spend much more time trying to find a mistake in my own code.
Basically, I was trying to parse a bunch of JSON-based tests, and in the middle of parsing was getting
It took a while to realize the reason for this. Indeed, serde_json can't return a slice if a string contained escaped characters, as in that case it must create a heap-allocated copy to unescape them.
Would it make sense to improve error message to clarify this?
Or maybe, deserializer could somehow return references to temporarily allocated strings to make these cases transparent to consumer (not sure if that's possible though)?
Or maybe better to prohibit deserializing slices altogether in deserializers that might need unescaping, for consistency?
In any case, it would be nice to clarify this situation.