Skip to content

Commit

Permalink
feat: complete Rust API Checklist before publishing (#5)
Browse files Browse the repository at this point in the history
* chore: create changelog

* chore: rename `enable-serde` feature to `serde`

* feat: add derives or implementations of common traits

* feat: add `From<HashMap` and `From<BTreeMap>` implementations

* feat: implement `Extend`

* test: validate Send and Sync implementations

* chore: remove redundant `Cargo.toml` metadata

* style: run clippy & fmt
  • Loading branch information
calteran authored Dec 11, 2023
1 parent 9014c3e commit 1b7982e
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 6 deletions.
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.1.0] - 2023-12-11
### Added
- Initial release
- `FixedIndexVec` struct
- `FixedIndexVec::new()` constructor
- `FixedIndexVec::push(value)` method
- `FixedIndexVec::insert(value)` method
- `FixedIndexVec::remove(index)` method
- `FixedIndexVec::get(index)` method
- `FixedIndexVec::iter()` method
- `FixedIndexVec::len()` method
- `FixedIndexVec::is_empty()` method
- `FixedIndexVec::clear()` method
- `FixedIndexVec::reset()` method
- `FixedIndexVec::next_index()` method
- `FixedIndexVec::first()` method
- `FixedIndexVec::last()` method
7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
name = "fixed-index-vec"
version = "0.1.0"
edition = "2021"
license-file = "LICENSE"
description = "A vector-like data structure whose indices do not change when elements are removed."
repository = "https://github.com/calteran/fixed-index-vec"
readme = "README.md"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
serde = { version = "1.0", optional = true, features = ["derive"] }

[features]
enable_serde = ["serde"]
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ use fixed_index_vec::FixedIndexVec;

## Features

- `enable-serde`: Enables serialization and deserialization of `FixedIndexVec` with [Serde](https://serde.rs/). Requires `FixedIndexVec` to contain values that implement `Serialize` and `DeserializeOwned`.
- `serde`: Enables serialization and deserialization of `FixedIndexVec` with [Serde](https://serde.rs/). Requires `FixedIndexVec` to contain values that implement `Serialize` and `DeserializeOwned`.

## Example

Expand Down
55 changes: 53 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![deny(missing_docs)]
#![doc = include_str!("../README.md")]
use std::collections::BTreeMap;
use std::collections::{BTreeMap, HashMap};
use std::fmt::Display;

/// A fixed-size indexed vector that maps indices to values.
///
Expand Down Expand Up @@ -33,13 +34,23 @@ use std::collections::BTreeMap;
/// - The `FixedIndexVec` is backed by a `BTreeMap`, so it is not as fast as a `Vec`.
/// - Index notations are supported (eg. `vec[0]`), however, accessing an index that does not
/// exist will panic.
#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct FixedIndexVec<T> {
map: BTreeMap<usize, T>,
next_index: usize,
}

impl<T: Display> Display for FixedIndexVec<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut s = String::new();
for (i, v) in self.iter() {
s.push_str(&format!("{}: {}\n", i, v));
}
write!(f, "{}", s)
}
}

impl<T> FixedIndexVec<T> {
/// Creates an empty `FixedIndexVec`.
///
Expand Down Expand Up @@ -314,8 +325,48 @@ impl<T> FromIterator<T> for FixedIndexVec<T> {
}
}

impl<T> Extend<T> for FixedIndexVec<T> {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
for v in iter.into_iter() {
self.push(v);
}
}
}

impl<T> From<Vec<T>> for FixedIndexVec<T> {
fn from(vec: Vec<T>) -> FixedIndexVec<T> {
vec.into_iter().collect()
}
}

impl<T, A> From<HashMap<A, T>> for FixedIndexVec<T> {
fn from(map: HashMap<A, T>) -> FixedIndexVec<T> {
map.into_values().collect()
}
}

impl<T, A> From<BTreeMap<A, T>> for FixedIndexVec<T> {
fn from(map: BTreeMap<A, T>) -> FixedIndexVec<T> {
map.into_values().collect()
}
}

#[cfg(test)]
mod tests {
use super::FixedIndexVec;

#[test]
fn test_send() {
fn assert_send<T: Send>() {}
assert_send::<FixedIndexVec<i32>>();
assert_send::<FixedIndexVec<f32>>();
assert_send::<FixedIndexVec<String>>();
}
#[test]
fn test_sync() {
fn assert_sync<T: Sync>() {}
assert_sync::<FixedIndexVec<i32>>();
assert_sync::<FixedIndexVec<f32>>();
assert_sync::<FixedIndexVec<String>>();
}
}

0 comments on commit 1b7982e

Please sign in to comment.