I'm trying to write a generic parsing function that can parse a comma-separated string of values using a parsing function passed-in by the caller and return a vector of Option. The caller also send a total_size (usize) thats used (explained below) when input string is None.
Some rules of the parser:
- if input string is None, return a vector with "total_size" number of values set to None
- if any token is empty, its corresponding value in vector should be None
- if parsing of individual items fails, return an error (the parser function sent by the caller returns a Result.
Eg: "1,2,3,,5" should parse to Result<[Some(1), Some(2), Some(3), None, Some(5)]>
I have to parse many such string with different custom types (which I intend to parse using serde_json
).
Here's how I've tried to implement it, but having trouble getting it to compile.
fn tokenize<F, T>(input: Option<String>, total: usize, parse_fn: F) -> Result<Vec<Option<Result<T, String>>>, String>
where
F: Fn(&str) -> Result<T, String>,
{
match input {
Some(s) => {
let tokens: Vec<&str> = s.split(',').collect();
let mut result: Vec<Option<Result<T, String>>> = Vec::with_capacity(total);
for token in tokens {
let val = if token.is_empty() {
None
} else {
match parse_fn(token) {
Ok(num) => Some(Ok(num)),
Err(e) => Some(Err(format!("Failed to parse token {}: {}", token, e))),
}
};
result.push(val);
}
if result.len() < total {
result.resize_with(total, || None);
}
Ok(result)
}
None => Ok(vec![None; total]),
}
}
The error I get is:
error[E0277]: the trait bound `Result<T, String>: Clone` is not satisfied
--> src/main.rs:25:25
|
25 | None => Ok(vec![None; total]),
| -----^^^^--------
| | |
| | the trait `Clone` is not implemented for `Result<T, String>`
| required by a bound introduced by this call
|
= note: required for `Result<T, String>` to implement `Clone`
= note: 1 redundant requirement hidden
= note: required for `Option<Result<T, String>>` to implement `Clone`
I'm not sure this is the right way to go about it. I'm also struggling to figure the syntax for "invoking" tokenize
function.