mirror of
https://github.com/bevyengine/bevy.git
synced 2026-05-06 06:06:42 -04:00
Don't panic in AssetPath deserialization (#23935)
## Objective
`AssetPath` deserialization panics if the path is malformed. This seems
a bit rude, and prevents the user from getting deserialization errors
that would help track down the problem.
## Solution
Instead of calling `AssetPath::parse`, call `AssetPath::try_parse` and
handle any errors.
Now, calling `ron::de::from_str` on `"a/b.test#"` returns a useful
error:
```rust
Err(SpannedError {
code: Message(
"Asset label must be at least one character. Either specify the label after the '#' or remove the '#'",
),
span: Span {
start: Position { line: 1, col: 2, },
end: Position { line: 1, col: 12 },
},
})
```
The PR also removes the `visit_string` method of the `AssetPath`
deserializer. `visit_string` is an optimization that avoids copies when
the deserializer can take ownership of the string (see [serde
docs](https://docs.rs/serde/latest/serde/de/trait.Visitor.html#method.visit_string)).
But `AssetPath` didn't take ownership of the string, so there's no
reason to implement it.
## Testing
```sh
cargo test -p bevy_asset
cargo run --example world_serialization
```
This commit is contained in:
@@ -680,14 +680,10 @@ impl<'de> Visitor<'de> for AssetPathVisitor {
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
Ok(AssetPath::parse(v).into_owned())
|
||||
}
|
||||
|
||||
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
Ok(AssetPath::from(v))
|
||||
match AssetPath::try_parse(v) {
|
||||
Ok(path) => Ok(path.into_owned()),
|
||||
Err(err) => Err(E::custom(err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -772,6 +768,12 @@ mod tests {
|
||||
assert_eq!(result, Err(crate::ParseAssetPathError::MissingLabel));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialize() {
|
||||
assert!(ron::de::from_str::<AssetPath>("\"a/b.test\"").is_ok());
|
||||
assert!(ron::de::from_str::<AssetPath>("\"a/b.test#\"").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parent() {
|
||||
// Parent consumes path segments, returns None when insufficient
|
||||
|
||||
Reference in New Issue
Block a user