Skip to content

Accept expression for capacity and length in vec macro #41

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,20 @@ jobs:
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: lcov.info

examples:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}

- uses: dtolnay/rust-toolchain@stable

- run: make examples
12 changes: 10 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
.SILENT:
.PHONY: fuzz
.PHONY: fuzz examples

# VS Code: Ctrl+Shift+B
all: test fmt lint build-doc
all: test fmt lint build-doc examples

test:
cargo test
Expand Down Expand Up @@ -37,6 +37,11 @@ build-doc:
fuzz:
cargo +nightly fuzz run static_vector

examples:
for ex in $$(cargo metadata --format-version=1 --no-deps | jq -r '.packages[].targets[] | select(.kind[] == "example") | .name'); do \
cargo run --example $$ex; \
done

dev:
echo Installing pre-commit hook...
curl -1sLf 'https://dl.cloudsmith.io/public/evilmartians/lefthook/setup.deb.sh' | sudo -E bash
Expand All @@ -51,6 +56,9 @@ dev:
echo Installing cargo-fuzz...
cargo install cargo-fuzz

echo Installing jq...
sudo apt install jq -y

deny-commit-on-master:
ifeq ($(shell git symbolic-ref --short HEAD),master)
$(error Direct commits to 'master' are not allowed.)
Expand Down
67 changes: 67 additions & 0 deletions examples/history.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use static_vector::{Vec, vec};

#[derive(Debug, PartialEq, Clone, Copy)]
enum Event {
Start,
Load,
Run,
Pause,
Resume,
Stop,
Exit,
}

struct EventHistory<const N: usize> {
events: Vec<Event, N>,
}

impl<const N: usize> EventHistory<N> {
const fn new() -> Self {
Self { events: vec![Event; N] }
}

fn insert(&mut self, event: Event) {
if self.events.is_full() {
// Remove the oldest event (FIFO)
let len = self.events.len();
self.events.as_mut_slice().copy_within(1..len, 0);

// Can ignore the error here since we are guaranteed to have at least one element
// because the vector is full.
let _ = self.events.pop();
}

// Can ignore the error here since we are guaranteed to have space after popping
// if the vector was full.
let _ = self.events.push(event);
}

const fn get_events(&self) -> &[Event] {
self.events.as_slice()
}
}

// Example of using static_vector to maintain a history of events
fn main() {
const HISTORY_SIZE: usize = 5;
let mut history = EventHistory::<HISTORY_SIZE>::new();

let events = [
Event::Start,
Event::Load,
Event::Run,
Event::Pause,
Event::Resume,
Event::Stop,
Event::Exit,
];
for &event in &events {
history.insert(event);
}

assert_eq!(
history.get_events(),
&[Event::Run, Event::Pause, Event::Resume, Event::Stop, Event::Exit],
"Expected history to contain the last 5 events"
);
}
39 changes: 33 additions & 6 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
/// let vec = vec![u16; 8; 5]; // Vector with capacity 8, length set to 5, initialized with zeros
/// ```
macro_rules! vec {
($type:ty; $capacity:literal) => {
($type:ty; $capacity:expr) => {
$crate::Vec::<$type, $capacity>::new()
};

Expand All @@ -45,15 +45,15 @@ macro_rules! vec {
}
};

($capacity:literal; $($value:expr),+ $(,)?) => {
($capacity:expr; $($value:expr),+ $(,)?) => {
{
let mut vec = $crate::Vec::<_, $capacity>::new();
vec.extend_from_slice(&[$($value),+]).expect("length is less than or equal to capacity");
vec
}
};

($type:ty; $capacity:literal; $length:literal) => {
($type:ty; $capacity:expr; $length:expr) => {
{
let mut vec = $crate::Vec::<$type, $capacity>::new();
vec.set_len($length).expect("length is less than or equal to capacity");
Expand All @@ -65,12 +65,20 @@ macro_rules! vec {
#[cfg(test)]
mod tests {
#[test]
fn vec_with_type_and_capacity() {
fn vec_with_type_and_capacity_literal() {
let vec = vec![i32; 10];
assert_eq!(vec.capacity(), 10);
assert!(vec.is_empty());
}

#[test]
fn vec_with_type_and_capacity_constant() {
const CAPACITY: usize = 10;
let vec = vec![i32; CAPACITY];
assert_eq!(vec.capacity(), 10);
assert!(vec.is_empty());
}

#[test]
#[should_panic(expected = "CAPACITY must be greater than 0")]
fn vec_with_type_and_capacity_zero() {
Expand All @@ -94,27 +102,46 @@ mod tests {
}

#[test]
fn vec_with_capacity_and_elements() {
fn vec_with_capacity_literal_and_elements() {
let vec = vec![10; 1, 2, 3];
assert_eq!(vec.capacity(), 10);
assert_eq!(vec.len(), 3);
assert_eq!(vec.as_slice(), &[1, 2, 3]);
}

#[test]
fn vec_with_capacity_constants_and_elements() {
const CAPACITY: usize = 10;
let vec = vec![CAPACITY; 1, 2, 3];
assert_eq!(vec.capacity(), 10);
assert_eq!(vec.len(), 3);
assert_eq!(vec.as_slice(), &[1, 2, 3]);
}

#[test]
#[should_panic(expected = "length is less than or equal to capacity: CapacityError")]
fn vec_with_more_elements_than_capacity() {
let _ = vec![2; 1, 2, 3];
}

#[test]
fn vec_with_capacity_and_length() {
fn vec_with_capacity_and_length_literals() {
let vec = vec![i32; 10; 3];
assert_eq!(vec.capacity(), 10);
assert_eq!(vec.len(), 3);
assert_eq!(vec.as_slice(), &[0, 0, 0]);
}

#[test]
fn vec_with_capacity_and_length_constants() {
const CAPACITY: usize = 10;
const LENGTH: usize = 3;
let vec = vec![i32; CAPACITY; LENGTH];
assert_eq!(vec.capacity(), 10);
assert_eq!(vec.len(), 3);
assert_eq!(vec.as_slice(), &[0, 0, 0]);
}

#[test]
fn vec_with_capacity_and_length_zero() {
let vec = vec![i32; 10; 0];
Expand Down