str_newtype/
lib.rs

1//! This library provides a handy derive macro to create type-safe wrappers
2//! around borrowed and owned string types (`str` and `String`), guaranteeing
3//! through the type system that those string have been validated.
4//!
5//! With this derive macro, all you need to do is define the base borrowed type,
6//! specify the name of the associated owned type and what trait you want them
7//! to implement.
8//!
9//! # Example
10//!
11//! In this example, we wish to define the types `FooStr` and `FooString`,
12//! similar to `str` (borrowed) and `String` (owned), with the extra guarantee
13//! that the string is always equal to `"foo"`.
14//!
15//! ```
16//! use str_newtype::StrNewType;
17//!
18//! /// An `str` that is equal to `"foo"`.
19//! #[derive(StrNewType)]
20//! #[newtype(owned(FooString))]
21//! pub struct FooStr(str);
22//!
23//! impl FooStr {
24//!   pub const fn validate_bytes(s: &[u8]) -> bool {
25//!     s.len() == 3 && s[0] == b'f' && s[1] == b'f' && s[2] == b'f'
26//!   }
27//!
28//!   pub const fn validate_str(s: &str) -> bool {
29//!     Self::validate_bytes(s.as_bytes())
30//!   }
31//! }
32//! ```
33//!
34//! The validation methods (`validate_*`) are provided by us, but `StrNewType`
35//! will use them to derive the following:
36//! - An error type `InvalidFooStr<T = String>(pub T)`;
37//! - A constructor `FooStr::new<T: ?Sized + AsRef<[u8]>>(input: &T) -> Result<&Self, InvalidFooStr<&T>>`
38//! - `FooStr: Deref<Target = str>` implementation
39//! - `FooStr: AsRef<str>` implementation
40//! - `FooStr: Borrow<str>` implementation
41//!
42//! Since we added the `owned(FooString)` attribute, it will also generate:
43//! - A sized/owned version of `FooStr`: `struct FooString(String);`
44//! - A constructor `FooString::new<T: Buffer>(s: T) -> Result<Self, InvalidFooStr<T>>`
45//! - `FooString: Deref<Target = FooStr>`
46//! - `FooString: AsRef<FooStr>` implementation
47//! - `FooString: Borrow<FooStr>` implementation
48//!
49//! And much more. See the the [`StrNewType`] documentation for a full
50//! specification of what items are derived and how it can be controlled with
51//! the `newtype` attribute.
52pub use str_newtype_derive::StrNewType;
53
54/// Trusted byte buffer type.
55///
56/// # Safety
57///
58/// Any interior mutability in the buffer type must not affect the `as_bytes`
59/// and `into_bytes` methods. In other words, as long as `self` is borrowed
60/// immutably those functions must always return the same result.
61pub unsafe trait Buffer: Sized {
62	/// Borrows the buffer bytes.
63	fn as_bytes(&self) -> &[u8];
64
65	/// Turns this buffer into a byte array.
66	fn into_bytes(self) -> Vec<u8>;
67}
68
69unsafe impl Buffer for Vec<u8> {
70	fn as_bytes(&self) -> &[u8] {
71		self
72	}
73
74	fn into_bytes(self) -> Vec<u8> {
75		self
76	}
77}
78
79unsafe impl Buffer for String {
80	fn as_bytes(&self) -> &[u8] {
81		self.as_bytes()
82	}
83
84	fn into_bytes(self) -> Vec<u8> {
85		self.into_bytes()
86	}
87}