diff --git a/Cargo.lock b/Cargo.lock index 6dcd824..e879d01 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,7 @@ checksum = "88eeeb1a5ef57ab0d40fb7a256e1b211496f97d6a8664ef52c0a665ce69a4e0f" [[package]] name = "rusl" -version = "0.2.0" +version = "0.2.1" dependencies = [ "linux-rust-bindings", "sc", @@ -31,7 +31,7 @@ dependencies = [ [[package]] name = "tiny-std" -version = "0.2.0" +version = "0.2.1" dependencies = [ "rusl", "sc", diff --git a/Todo.md b/Todo.md index 9195ea6..d58ada6 100644 --- a/Todo.md +++ b/Todo.md @@ -18,4 +18,7 @@ for applications that can be threaded. 14. [ ] Use more efficient syscall semantics, i.e. `eax` over `rax` if the return-value isn't register size. 15. [ ] Use type-checked builders as args for comptime error evaluation of syscalls. 16. [ ] Enforce correct features for symbol relocation through a build-script (Fail compilation with -static relocation if `aux` feature isn't enabled, since that will result in a botched binary). \ No newline at end of file +static relocation if `aux` feature isn't enabled, since that will result in a botched binary). +17. [ ] Path operations on &UnixStr +18. [x] Implement `from_str` on &UnixStr +19. [x] Throw a rusl::Error instead of Utf8Error on `as_str` \ No newline at end of file diff --git a/rusl/Cargo.toml b/rusl/Cargo.toml index 2446881..9debe77 100644 --- a/rusl/Cargo.toml +++ b/rusl/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rusl" -version = "0.2.0" +version = "0.2.1" edition = "2021" license = "MPL-2.0" readme = "../Readme.md" diff --git a/rusl/Changelog.md b/rusl/Changelog.md index f963bef..a839372 100644 --- a/rusl/Changelog.md +++ b/rusl/Changelog.md @@ -11,6 +11,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Changed +## [v0.2.1] - 2023-10-01 + +### Changed +- Throw a rusl error instead of a Utf8Error on failed `UnixStr` conversions. + ## [v0.2.0] - 2023-10-01 ### Changed diff --git a/rusl/src/string/unix_str.rs b/rusl/src/string/unix_str.rs index b7eead6..7eafca5 100644 --- a/rusl/src/string/unix_str.rs +++ b/rusl/src/string/unix_str.rs @@ -3,17 +3,28 @@ use crate::Error; use alloc::string::String; #[cfg(feature = "alloc")] use alloc::vec::Vec; +use core::fmt::{Debug, Formatter}; use core::hash::Hasher; -use core::str::Utf8Error; use crate::platform::NULL_BYTE; use crate::string::strlen::strlen; #[cfg(feature = "alloc")] #[repr(transparent)] -#[derive(Debug, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)] +#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd)] pub struct UnixString(pub(crate) Vec); +#[cfg(feature = "alloc")] +impl Debug for UnixString { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + let slice = unsafe { core::slice::from_raw_parts(self.0.as_ptr(), self.0.len()) }; + match core::str::from_utf8(slice) { + Ok(raw) => f.write_fmt(format_args!("UnixString({raw})")), + Err(_e) => f.write_fmt(format_args!("UnixString({slice:?})")), + } + } +} + #[cfg(feature = "alloc")] impl UnixString { #[inline] @@ -97,7 +108,7 @@ impl AsRef for UnixString { } #[repr(transparent)] -#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Eq, PartialEq, Ord, PartialOrd)] pub struct UnixStr(pub(crate) [u8]); impl UnixStr { @@ -168,9 +179,9 @@ impl UnixStr { /// Try to convert this `&UnixStr` to a utf8 `&str` /// # Errors /// Not utf8 - pub fn as_str(&self) -> Result<&str, Utf8Error> { + pub fn as_str(&self) -> Result<&str, Error> { let slice = unsafe { core::slice::from_raw_parts(self.0.as_ptr(), self.0.len() - 1) }; - core::str::from_utf8(slice) + Ok(core::str::from_utf8(slice)?) } /// Get this `&UnixStr` as a slice, including the null byte @@ -238,6 +249,16 @@ impl UnixStr { } } +impl<'a> Debug for &'a UnixStr { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + let slice = unsafe { core::slice::from_raw_parts(self.0.as_ptr(), self.0.len()) }; + match core::str::from_utf8(slice) { + Ok(inner) => f.write_fmt(format_args!("UnixStr({inner})")), + Err(_e) => f.write_fmt(format_args!("UnixStr({slice:?})")), + } + } +} + impl<'a> core::hash::Hash for &'a UnixStr { #[inline] fn hash(&self, state: &mut H) { @@ -253,6 +274,16 @@ impl From<&UnixStr> for UnixString { } } +#[cfg(feature = "alloc")] +impl core::str::FromStr for UnixString { + type Err = Error; + + #[inline] + fn from_str(s: &str) -> Result { + Self::try_from_str(s) + } +} + #[inline] const fn const_null_term_validate(s: &[u8]) { assert!( diff --git a/test-runners/alloc-st-main/Cargo.lock b/test-runners/alloc-st-main/Cargo.lock index f208411..235085c 100644 --- a/test-runners/alloc-st-main/Cargo.lock +++ b/test-runners/alloc-st-main/Cargo.lock @@ -18,7 +18,7 @@ checksum = "88eeeb1a5ef57ab0d40fb7a256e1b211496f97d6a8664ef52c0a665ce69a4e0f" [[package]] name = "rusl" -version = "0.2.0" +version = "0.2.1" dependencies = [ "linux-rust-bindings", "sc", @@ -47,7 +47,7 @@ dependencies = [ [[package]] name = "tiny-std" -version = "0.2.0" +version = "0.2.1" dependencies = [ "rusl", "sc", diff --git a/test-runners/no-alloc-main/Cargo.lock b/test-runners/no-alloc-main/Cargo.lock index d4fa9a7..728a4f3 100644 --- a/test-runners/no-alloc-main/Cargo.lock +++ b/test-runners/no-alloc-main/Cargo.lock @@ -18,7 +18,7 @@ dependencies = [ [[package]] name = "rusl" -version = "0.2.0" +version = "0.2.1" dependencies = [ "linux-rust-bindings", "sc", @@ -47,7 +47,7 @@ dependencies = [ [[package]] name = "tiny-std" -version = "0.2.0" +version = "0.2.1" dependencies = [ "rusl", "sc", diff --git a/test-runners/test-lib/src/lib.rs b/test-runners/test-lib/src/lib.rs index e000c91..877553c 100644 --- a/test-runners/test-lib/src/lib.rs +++ b/test-runners/test-lib/src/lib.rs @@ -52,7 +52,7 @@ fn run_minimal_feature_set() { fn get_env() { let v_unix = tiny_std::env::var_unix(UnixStr::try_from_str("HOME\0").unwrap()).unwrap(); let v = tiny_std::env::var("HOME").unwrap(); - assert_eq!(v, v_unix); + assert_eq!(v, v_unix.as_str().unwrap()); if is_ci() { assert_eq!("/home/runner", v); } else { diff --git a/test-runners/threaded-main/Cargo.lock b/test-runners/threaded-main/Cargo.lock index 9c745cf..1d05d60 100644 --- a/test-runners/threaded-main/Cargo.lock +++ b/test-runners/threaded-main/Cargo.lock @@ -10,7 +10,7 @@ checksum = "88eeeb1a5ef57ab0d40fb7a256e1b211496f97d6a8664ef52c0a665ce69a4e0f" [[package]] name = "rusl" -version = "0.2.0" +version = "0.2.1" dependencies = [ "linux-rust-bindings", "sc", @@ -47,7 +47,7 @@ dependencies = [ [[package]] name = "tiny-std" -version = "0.2.0" +version = "0.2.1" dependencies = [ "rusl", "sc", diff --git a/tiny-std/Cargo.toml b/tiny-std/Cargo.toml index 55c0e58..e474270 100644 --- a/tiny-std/Cargo.toml +++ b/tiny-std/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tiny-std" -version = "0.2.0" +version = "0.2.1" edition = "2021" license = "MPL-2.0" readme = "../Readme.md" diff --git a/tiny-std/Changelog.md b/tiny-std/Changelog.md index c3bf5b9..9ace7b5 100644 --- a/tiny-std/Changelog.md +++ b/tiny-std/Changelog.md @@ -11,6 +11,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Changed +## [v0.2.1] - 2023-10-01 + +### Changed +- Expose errors at crate root + ## [v0.2.0] - 2023-10-01 ### Fixed - Create dir all used to error when it ended with a slash diff --git a/tiny-std/src/env.rs b/tiny-std/src/env.rs index 74215d3..368e4cb 100644 --- a/tiny-std/src/env.rs +++ b/tiny-std/src/env.rs @@ -1,5 +1,6 @@ use core::str::Utf8Error; +use crate::error::Error; use rusl::string::strlen::strlen; use rusl::string::unix_str::UnixStr; @@ -27,7 +28,7 @@ pub enum VarError { /// # Errors /// 1. Value is not in the environment /// 2. Value exists but is not utf-8 -pub fn var_unix(key: &UnixStr) -> Result<&'static str, VarError> { +pub fn var_unix(key: &UnixStr) -> Result<&'static UnixStr, VarError> { let mut env_ptr = unsafe { ENV.env_p }; while !env_ptr.is_null() { unsafe { @@ -40,10 +41,9 @@ pub fn var_unix(key: &UnixStr) -> Result<&'static str, VarError> { if match_up_to != 0 { // Next is '=' if var_ptr.add(match_up_to).read() == b'=' { - let value_len = strlen(var_ptr.add(match_up_to + 1)); - let value_slice = - core::slice::from_raw_parts(var_ptr.add(match_up_to + 1), value_len); - return core::str::from_utf8(value_slice).map_err(VarError::NotUnicode); + // # Safety + // Trusting the OS to null terminate + return Ok(UnixStr::from_ptr(var_ptr.add(match_up_to + 1))); } } @@ -103,11 +103,11 @@ pub fn args_os() -> ArgsOs { pub struct Args(ArgsOs); impl Iterator for Args { - type Item = Result<&'static str, Utf8Error>; + type Item = Result<&'static str, Error>; #[inline] fn next(&mut self) -> Option { - self.0.next().map(UnixStr::as_str) + self.0.next().map(|e| Ok(UnixStr::as_str(e)?)) } } diff --git a/tiny-std/src/error.rs b/tiny-std/src/error.rs index 22c8acd..41913ab 100644 --- a/tiny-std/src/error.rs +++ b/tiny-std/src/error.rs @@ -1,6 +1,6 @@ use core::fmt::{Debug, Display, Formatter}; -pub use rusl::error::Errno; +use rusl::error::Errno; pub type Result = core::result::Result; diff --git a/tiny-std/src/lib.rs b/tiny-std/src/lib.rs index 42a83ff..9e89adb 100644 --- a/tiny-std/src/lib.rs +++ b/tiny-std/src/lib.rs @@ -9,14 +9,17 @@ #[cfg(feature = "alloc")] extern crate alloc; +pub use error::{Error, Result}; +pub use rusl::error::Errno; pub use rusl::string::unix_str::*; +pub use rusl::Error as RuslError; #[cfg(feature = "allocator-provided")] pub mod allocator; pub mod elf; #[cfg(feature = "start")] pub mod env; -pub mod error; +mod error; pub mod fs; pub mod io; pub mod linux;