Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AssetPath source parse fix #11543

Merged
merged 12 commits into from
Jan 26, 2024
53 changes: 20 additions & 33 deletions crates/bevy_asset/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,6 @@ impl<'a> Display for AssetPath<'a> {

#[derive(Error, Debug, PartialEq, Eq)]
pub enum ParseAssetPathError {
alice-i-cecile marked this conversation as resolved.
Show resolved Hide resolved
#[error("Asset source must be followed by '://'")]
InvalidSourceSyntax,
#[error("Asset source must be at least one character. Either specify the source before the '://' or remove the `://`")]
MissingSource,
#[error("Asset label must be at least one character. Either specify the label after the '#' or remove the '#'")]
Expand Down Expand Up @@ -129,36 +127,22 @@ impl<'a> AssetPath<'a> {
fn parse_internal(
asset_path: &str,
) -> Result<(Option<&str>, &Path, Option<&str>), ParseAssetPathError> {
let mut chars = asset_path.char_indices();
let mut source_range = None;
let mut path_range = 0..asset_path.len();
let mut label_range = None;
while let Some((index, char)) = chars.next() {
match char {
':' => {
let (_, char) = chars
.next()
.ok_or(ParseAssetPathError::InvalidSourceSyntax)?;
if char != '/' {
return Err(ParseAssetPathError::InvalidSourceSyntax);
}
let (index, char) = chars
.next()
.ok_or(ParseAssetPathError::InvalidSourceSyntax)?;
if char != '/' {
return Err(ParseAssetPathError::InvalidSourceSyntax);
}
source_range = Some(0..index - 2);
path_range.start = index + 1;
}
'#' => {
path_range.end = index;
label_range = Some(index + 1..asset_path.len());
break;
}
_ => {}

let source_range = match asset_path.find("://") {
Some(index) => {
path_range.start = index + 3;
Some(0..index)
}
}
None => None,
};
let label_range = match asset_path.rfind('#') {
Some(index) => {
path_range.end = index;
Some(index + 1..asset_path.len())
}
None => None,
};

let source = match source_range {
Some(source_range) => {
Expand Down Expand Up @@ -700,6 +684,12 @@ mod tests {
Ok((Some("http"), Path::new("a/b.test"), Some("Foo")))
);

let result = AssetPath::parse_internal("http://localhost:80/b.test");
assert_eq!(
result,
Ok((Some("http"), Path::new("localhost:80/b.test"), None))
);

let result = AssetPath::parse_internal("http://");
assert_eq!(result, Ok((Some("http"), Path::new(""), None)));

Expand All @@ -708,9 +698,6 @@ mod tests {

let result = AssetPath::parse_internal("a/b.test#");
assert_eq!(result, Err(crate::ParseAssetPathError::MissingLabel));

let result = AssetPath::parse_internal("http:/");
assert_eq!(result, Err(crate::ParseAssetPathError::InvalidSourceSyntax));
}

#[test]
Expand Down
Loading