Skip to content

Commit 681b3c4

Browse files
committed
Polish for release
1 parent 0bad913 commit 681b3c4

File tree

7 files changed

+92
-13
lines changed

7 files changed

+92
-13
lines changed

Cargo.toml

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
[package]
22
name = "small-fixed-array"
3+
description = "A crate providing fixed length immutable collections with a low memory footprint."
4+
repository = "https://github.com/GnomedDev/small-fixed-array"
35
version = "0.1.0"
46
edition = "2021"
5-
6-
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
license = "MIT"
78

89
[dependencies]
910
serde = { version = "1.0.193", optional = true }

LICENCE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2023-Present David Thomas
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# small-fixed-array
2+
3+
See [module documentation](https://docs.rs/small-fixed-array) or use `cargo doc --open`.

src/array.rs

+25-4
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,61 @@ use std::{fmt::Debug, hash::Hash};
22

33
use crate::non_empty_array::NonEmptyFixedArray;
44

5-
/// A fixed size array with length provided at creation with length denoted in [`u32`]
5+
/// A fixed size array with length provided at creation denoted in [`u32`]
6+
///
7+
/// See module level documentation for more information.
68
#[derive(Clone)]
79
pub struct FixedArray<T>(Option<NonEmptyFixedArray<T>>);
810

911
impl<T> FixedArray<T> {
12+
/// Alias to [`FixedArray::empty`].
13+
#[must_use]
1014
pub fn new() -> Self {
1115
Self::empty()
1216
}
1317

18+
/// Creates a new, empty [`FixedArray`] that cannot be pushed to.
19+
#[must_use]
1420
pub fn empty() -> Self {
1521
Self(None)
1622
}
1723

24+
/// Returns the length of the [`FixedArray`].
25+
#[must_use]
1826
pub fn len(&self) -> u32 {
1927
self.0
2028
.as_ref()
2129
.map(NonEmptyFixedArray::small_len)
2230
.unwrap_or_default()
2331
}
2432

33+
/// Returns if the length is equal to 0.
34+
#[must_use]
2535
pub fn is_empty(&self) -> bool {
2636
self.0.is_none()
2737
}
2838

39+
/// Converts [`FixedArray<T>`] to [`Vec<T>`], this operation should be cheap.
40+
#[must_use]
41+
pub fn into_vec(self) -> Vec<T> {
42+
self.into()
43+
}
44+
45+
/// Converts `&`[`FixedArray<T>`] to `&[T]`, this conversion can be performed by [`std::ops::Deref`].
46+
#[must_use]
2947
pub fn as_slice(&self) -> &[T] {
3048
self
3149
}
3250

33-
pub fn into_vec(self) -> Vec<T> {
34-
self.into()
51+
/// Converts `&mut `[`FixedArray<T>`] to `&mut [T]`, this conversion can be performed by [`std::ops::DerefMut`].
52+
#[must_use]
53+
pub fn as_slice_mut(&mut self) -> &mut [T] {
54+
self
3555
}
3656
}
3757

3858
impl<T> Default for FixedArray<T> {
59+
/// Creates a new, empty [`FixedArray`] that cannot be pushed to.
3960
fn default() -> Self {
4061
Self::empty()
4162
}
@@ -77,7 +98,7 @@ impl<T> std::ops::IndexMut<u32> for FixedArray<T> {
7798

7899
impl<T: Hash> Hash for FixedArray<T> {
79100
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
80-
self.as_slice().hash(state)
101+
self.as_slice().hash(state);
81102
}
82103
}
83104

src/lib.rs

+15
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
//! A crate for [`FixedArray`] and [`FixedString`], types to provide a smaller memory footprint in exchange for:
2+
//! - Immutablity, [`FixedArray`] and [`FixedString`] cannot be mutated without converting back to their expanded forms.
3+
//! - Maximum length, [`FixedArray`] and [`FixedString`] have a length cap of [`u32::MAX`] elements.
4+
//!
5+
//! These types provide cheap conversions to [`Vec`] and [`String`], to make up for most of these downsides, but it is
6+
//! still not recommended to use these collections for mutated values as you will see a performance downside.
7+
//!
8+
//! These can be thought of as `Box<[T]>` and `Box<str>`, except the length is denoted as a [`u32`].
9+
//!
10+
//! ## Features
11+
//! - `serde`: Provides [`serde`] implementations for [`FixedArray`] and [`FixedString`].
12+
//! - `typesize`: Provides [`typesize`] implementations for [`FixedArray`] and [`FixedString`].
13+
#![warn(clippy::pedantic)]
14+
#![allow(clippy::module_name_repetitions)]
15+
116
mod array;
217
mod string;
318
// Internal only!

src/non_empty_array.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ impl<T> NonEmptyFixedArray<T> {
2525
unsafe { std::slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len()) }
2626
}
2727

28-
/// Converts the NonEmptyFixedArray to it's original [`Box<T>`].
28+
/// Converts the [`NonEmptyFixedArray`] to it's original [`Box<T>`].
2929
///
3030
/// # Safety
31-
/// `self` must never be used again, and it is highly recommended to wrap in ManuallyDrop before calling.
31+
/// `self` must never be used again, and it is highly recommended to wrap in [`ManuallyDrop`] before calling.
3232
pub(crate) unsafe fn as_box(&mut self) -> Box<[T]> {
3333
let slice = self.as_mut_slice();
3434

@@ -40,7 +40,7 @@ impl<T> NonEmptyFixedArray<T> {
4040
impl<T> From<Box<[T]>> for NonEmptyFixedArray<T> {
4141
fn from(boxed_array: Box<[T]>) -> Self {
4242
let len = NonZeroU32::new(boxed_array.len().try_into().unwrap()).unwrap();
43-
let array_ptr = Box::into_raw(boxed_array) as *mut T;
43+
let array_ptr = Box::into_raw(boxed_array).cast::<T>();
4444

4545
NonEmptyFixedArray {
4646
ptr: NonNull::new(array_ptr).expect("Box ptr != nullptr"),
@@ -67,10 +67,8 @@ impl<T: Clone> Clone for NonEmptyFixedArray<T> {
6767

6868
impl<T> Drop for NonEmptyFixedArray<T> {
6969
fn drop(&mut self) {
70-
unsafe {
71-
// SAFETY: We never use `self` again, and we are in the drop impl.
72-
self.as_box();
73-
}
70+
// SAFETY: We never use `self` again, and we are in the drop impl.
71+
unsafe { self.as_box() };
7472
}
7573
}
7674

src/string.rs

+20
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,39 @@ use std::fmt::Write as _;
22

33
use crate::FixedArray;
44

5+
/// A fixed size String with length provided at creation denoted in [`u32`].
6+
///
7+
/// See module level documentation for more information.
58
#[derive(Default, Clone, Hash, PartialEq, Eq)]
69
#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
710
pub struct FixedString(FixedArray<u8>);
811

912
impl FixedString {
13+
#[must_use]
1014
pub fn new() -> Self {
1115
FixedString(FixedArray::default())
1216
}
1317

18+
/// Returns the length of the [`FixedString`].
19+
#[must_use]
20+
pub fn len(&self) -> u32 {
21+
self.0.len()
22+
}
23+
24+
/// Returns if the length is equal to 0.
25+
#[must_use]
26+
pub fn is_empty(&self) -> bool {
27+
self.0.is_empty()
28+
}
29+
30+
/// Converts `&`[`FixedString`] to `&str`, this conversion can be performed by [`std::ops::Deref`].
31+
#[must_use]
1432
pub fn as_str(&self) -> &str {
1533
self
1634
}
1735

36+
/// Converts [`FixedString`] to [`String`], this operation should be cheap.
37+
#[must_use]
1838
pub fn into_string(self) -> String {
1939
self.into()
2040
}

0 commit comments

Comments
 (0)