mirror of
https://github.com/storytold/storyteller-bevy.git
synced 2026-10-14 23:53:14 +00:00
7b06d48c5d
This PR adds Storyteller.ai API integration for saving and loading Storyteller Studio scenes to/from the backend. ### Known issues * The skybox is not currently stored in the serialized scene format
41 lines
1.2 KiB
Rust
41 lines
1.2 KiB
Rust
use std::{ffi::OsStr, path::Path};
|
|
|
|
pub trait PathExtras {
|
|
/// See [std::path::Path::file_prefix]
|
|
#[must_use]
|
|
fn ext_file_prefix(&self) -> Option<&OsStr>;
|
|
}
|
|
|
|
impl PathExtras for Path {
|
|
fn ext_file_prefix(&self) -> Option<&OsStr> {
|
|
self.file_name()
|
|
.map(split_file_at_dot)
|
|
.map(|(before, _after)| before)
|
|
}
|
|
}
|
|
|
|
/// Note: Copied from private fn `std::path::split_file_at_dot`
|
|
fn split_file_at_dot(file: &OsStr) -> (&OsStr, Option<&OsStr>) {
|
|
let slice = file.as_encoded_bytes();
|
|
if slice == b".." {
|
|
return (file, None);
|
|
}
|
|
|
|
// The unsafety here stems from converting between &OsStr and &[u8]
|
|
// and back. This is safe to do because (1) we only look at ASCII
|
|
// contents of the encoding and (2) new &OsStr values are produced
|
|
// only from ASCII-bounded slices of existing &OsStr values.
|
|
let i = match slice[1..].iter().position(|b| *b == b'.') {
|
|
Some(i) => i + 1,
|
|
None => return (file, None),
|
|
};
|
|
let before = &slice[..i];
|
|
let after = &slice[i + 1..];
|
|
unsafe {
|
|
(
|
|
OsStr::from_encoded_bytes_unchecked(before),
|
|
Some(OsStr::from_encoded_bytes_unchecked(after)),
|
|
)
|
|
}
|
|
}
|