How can I simplify this Rust code? Currently it's a bit hard to read due to complex nested blocks (11 levels) and many type conversion and unwraps. If possible, I want to return a Iterator.
The logic is pretty simple: The code tries to parse the reading list file of Safari, yield all items and simply ignore errors like missing fields. (See also the comments on the Python script)
I read the doc of the plist library, followed and tried and found using and_then API of Option in all cases even makes the code much more hard to read. Also, I have no idea about how to remove the unwraps:
Some of them maybe by return Result like the ones about path and reading file.
Some of them like the get and as_* returns seems difficult to handle, since the goal is to return all possible items and simply ignoring issues like missing fields.
Typically, if you know the structure of a piece of serialized data, you should not be traversing it manually. Instead, use Serde to deserialize it to a statically-typed object, and traverse that object.
Also, all the unwrap()s make your code considerably more verbose and less robust to failure. Propagate (using the postfix ? operator) or handle the errors.
In this case, isn't any None value from the Option will cause the function return None? But I want it just ignore the "issued" item. Like the check in the Python version:
Here's another edit with some cleanup's uses "let else" to ignore some errors in the format. I don't know which should be ignored and which imply the file is probably wrong, so I assumed unwrap meant the later.
I could have used Option<String> instead of String, but since empty URLs and empty titles aren't meaningful, I simply slapped a #[serde(default)] on the fields to simplify the handling of missing values (since you have to check the contents of one of the Titles anyway).