Skip to content

Commit

Permalink
Implement simple-ish proc macro cli (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcusGrass authored Nov 7, 2023
1 parent c132f94 commit e8873d4
Show file tree
Hide file tree
Showing 19 changed files with 2,234 additions and 5 deletions.
1 change: 1 addition & 0 deletions .local/lint-all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ cargo fmt --all --check
cd ../..
/bin/sh .local/rusl-lint.sh
/bin/sh .local/tiny-std-lint.sh
cargo clippy -p tiny-cli
3 changes: 2 additions & 1 deletion .local/test-all.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/bin/sh
set -ex
/bin/sh .local/rusl-test.sh
/bin/sh .local/tiny-std-test.sh
/bin/sh .local/tiny-std-test.sh
cargo test -p tiny-cli
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[workspace]
resolver = "2"
members = ["rusl", "tiny-start", "tiny-std"]
members = ["rusl", "tiny-cli", "tiny-start", "tiny-std"]
exclude = ["test-runners/alloc-st-main", "test-runners/no-alloc-main", "test-runners/threaded-main", "test-runners/test-lib"]
8 changes: 6 additions & 2 deletions rusl/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
### Fixed

### Added

### Changed

## [v0.2.2]
### Added
- Utility methods for `UnixStr` to make it easier to navigate them
as paths
- Find-method for `UnixStr`
- Accessors for some inner fields of `Statx`

### Changed
- `unix_lit!` macros

## [v0.2.1] - 2023-10-01

Expand Down
22 changes: 22 additions & 0 deletions rusl/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,25 @@ macro_rules! expect_errno {
assert_eq!($errno, $crate::errno_or_throw!($res));
};
}

/// comp-time-checked null-terminated string literal, adds null terminator.
/// Will fail to compile if invalid.
#[macro_export]
macro_rules! unix_lit {
($lit: literal) => {{
const __LIT_VAL: &$crate::string::unix_str::UnixStr =
$crate::string::unix_str::UnixStr::from_str_checked(concat!($lit, "\0"));
__LIT_VAL
}};
}

#[cfg(test)]
mod tests {
use crate::string::unix_str::UnixStr;

#[test]
fn lit_macro() {
let my_var = unix_lit!("hello");
assert_eq!(UnixStr::try_from_str("hello\0").unwrap(), my_var);
}
}
53 changes: 52 additions & 1 deletion rusl/src/string/unix_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,15 @@ impl UnixStr {

/// # Safety
/// `&str` needs to be null terminated or downstream UB may occur
#[inline]
#[must_use]
pub const unsafe fn from_str_unchecked(s: &str) -> &Self {
core::mem::transmute(s)
}

/// # Safety
/// `&[u8]` needs to be null terminated or downstream UB may occur
#[inline]
#[must_use]
pub const unsafe fn from_bytes_unchecked(s: &[u8]) -> &Self {
core::mem::transmute(s)
Expand Down Expand Up @@ -212,7 +214,7 @@ impl UnixStr {
/// Get this `&UnixStr` as a slice, including the null byte
#[inline]
#[must_use]
pub fn as_slice(&self) -> &[u8] {
pub const fn as_slice(&self) -> &[u8] {
&self.0
}

Expand Down Expand Up @@ -313,6 +315,36 @@ impl UnixStr {
true
}

/// Get the last component of a path, if possible.
///
/// # Example
/// ```
/// use rusl::string::unix_str::UnixStr;
/// use rusl::unix_lit;
/// fn get_file_paths() {
/// // Has no filename, just a root path
/// let a = unix_lit!("/");
/// assert_eq!(None, a.path_file_name());
/// // Has a 'filename'
/// let a = unix_lit!("/etc");
/// assert_eq!(Some(unix_lit!("etc")), a.path_file_name());
/// }
/// ```
#[must_use]
#[allow(clippy::borrow_as_ptr)]
pub fn path_file_name(&self) -> Option<&UnixStr> {
for (ind, byte) in self.0.iter().enumerate().rev() {
if *byte == b'/' {
return if ind + 2 < self.len() {
unsafe { Some(&*(&self.0[ind + 1..] as *const [u8] as *const Self)) }
} else {
None
};
}
}
None
}

/// Joins this [`UnixStr`] with some other [`UnixStr`] adding a slash if necessary.
/// Will make sure that there's at most one slash at the boundary but won't check
/// either string for "path validity" in any other case
Expand Down Expand Up @@ -768,6 +800,25 @@ mod tests {
assert_eq!("hello/there", new.as_str().unwrap());
}

#[test]
fn can_get_last_path_happy() {
let base = unix_lit!("a/b/c");
let res = base.path_file_name().unwrap();
let expect = unix_lit!("c");
assert_eq!(expect, res);
}

#[test]
fn can_get_last_path_root_gives_none() {
let base = unix_lit!("/");
assert!(base.path_file_name().is_none());
}

#[test]
fn can_get_last_path_empty_gives_none() {
assert!(UnixStr::EMPTY.path_file_name().is_none());
}

#[test]
fn find_parent_path_happy() {
let a = UnixStr::from_str_checked("hello/there/friend\0");
Expand Down
11 changes: 11 additions & 0 deletions tiny-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "tiny-cli"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
proc-macro = true

[dev-dependencies]
tiny-std = { path = "../tiny-std", features = ["alloc", "cli"]}
17 changes: 17 additions & 0 deletions tiny-cli/Changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Change Log
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]
### Fixed

### Added

### Changed

## [v0.1.0] - 2023-10-01

### Added
- Tiny-cli ArgParser
Loading

0 comments on commit e8873d4

Please sign in to comment.