You're Invited:Meet the Socket Team at RSAC and BSidesSF 2026, March 23–26.RSVP
Socket
Book a DemoSign in
Socket

tinystr

Package Overview
Dependencies
Maintainers
1
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tinystr - cargo Package Compare versions

Comparing version
0.7.1
to
0.7.2
+104
src/unvalidated.rs
// This file is part of ICU4X. For terms of use, please see the file
// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
use crate::TinyAsciiStr;
use crate::TinyStrError;
/// A fixed-length bytes array that is expected to be an ASCII string but does not enforce that invariant.
///
/// Use this type instead of `TinyAsciiStr` if you don't need to enforce ASCII during deserialization. For
/// example, strings that are keys of a map don't need to ever be reified as `TinyAsciiStr`s.
///
/// The main advantage of this type over `[u8; N]` is that it serializes as a string in
/// human-readable formats like JSON.
#[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy)]
pub struct UnvalidatedTinyAsciiStr<const N: usize>(pub(crate) [u8; N]);
impl<const N: usize> UnvalidatedTinyAsciiStr<N> {
#[inline]
// Converts into a [`TinyAsciiStr`]. Fails if the bytes are not valid ASCII.
pub fn try_into_tinystr(&self) -> Result<TinyAsciiStr<N>, TinyStrError> {
TinyAsciiStr::try_from_raw(self.0)
}
#[doc(hidden)]
pub const fn from_bytes_unchecked(bytes: [u8; N]) -> Self {
Self(bytes)
}
}
impl<const N: usize> TinyAsciiStr<N> {
#[inline]
// Converts into a [`UnvalidatedTinyAsciiStr`]
pub const fn to_unvalidated(self) -> UnvalidatedTinyAsciiStr<N> {
UnvalidatedTinyAsciiStr(*self.all_bytes())
}
}
#[cfg(feature = "serde")]
impl<const N: usize> serde::Serialize for UnvalidatedTinyAsciiStr<N> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::Error;
self.try_into_tinystr()
.map_err(|_| S::Error::custom("invalid ascii in UnvalidatedTinyAsciiStr"))?
.serialize(serializer)
}
}
macro_rules! deserialize {
($size:literal) => {
#[cfg(feature = "serde")]
impl<'de, 'a> serde::Deserialize<'de> for UnvalidatedTinyAsciiStr<$size>
where
'de: 'a,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
if deserializer.is_human_readable() {
Ok(TinyAsciiStr::deserialize(deserializer)?.to_unvalidated())
} else {
Ok(Self(<[u8; $size]>::deserialize(deserializer)?))
}
}
}
};
}
deserialize!(1);
deserialize!(2);
deserialize!(3);
deserialize!(4);
deserialize!(5);
deserialize!(6);
deserialize!(7);
deserialize!(8);
deserialize!(9);
deserialize!(10);
deserialize!(11);
deserialize!(12);
deserialize!(13);
deserialize!(14);
deserialize!(15);
deserialize!(16);
deserialize!(17);
deserialize!(18);
deserialize!(19);
deserialize!(20);
deserialize!(21);
deserialize!(22);
deserialize!(23);
deserialize!(24);
deserialize!(25);
deserialize!(26);
deserialize!(27);
deserialize!(28);
deserialize!(29);
deserialize!(30);
deserialize!(31);
deserialize!(32);
+1
-1
{
"git": {
"sha1": "196823aa3a859324cca61b61e7aafa4c98988f1a"
"sha1": "e16ba527854ca0edc36695e4e65fdcbc4dccd188"
},
"path_in_vcs": "utils/tinystr"
}

@@ -40,16 +40,4 @@ // This file is part of ICU4X. For terms of use, please see the file

group4.bench_function("TinyAsciiStr<4>", $action!(TinyAsciiStr<4>, STRINGS_4));
group4.bench_function(
"tinystr_old::TinyStr4",
$action!(tinystr_old::TinyStr4, STRINGS_4),
);
group4.bench_function("TinyAsciiStr<8>", $action!(TinyAsciiStr<8>, STRINGS_4));
group4.bench_function(
"tinystr_old::TinyStr8",
$action!(tinystr_old::TinyStr8, STRINGS_4),
);
group4.bench_function("TinyAsciiStr<16>", $action!(TinyAsciiStr<16>, STRINGS_4));
group4.bench_function(
"tinystr_old::TinyStr16",
$action!(tinystr_old::TinyStr16, STRINGS_4),
);
group4.finish();

@@ -61,10 +49,2 @@

group8.bench_function("TinyAsciiStr<16>", $action!(TinyAsciiStr<16>, STRINGS_8));
group8.bench_function(
"tinystr_old::TinyStr8",
$action!(tinystr_old::TinyStr8, STRINGS_8),
);
group8.bench_function(
"tinystr_old::TinyStr16",
$action!(tinystr_old::TinyStr16, STRINGS_8),
);
group8.finish();

@@ -75,8 +55,4 @@

group16.bench_function("TinyAsciiStr<16>", $action!(TinyAsciiStr<16>, STRINGS_16));
group16.bench_function(
"tinystr_old::TinyStr16",
$action!(tinystr_old::TinyStr16, STRINGS_16),
);
group16.finish();
};
}

@@ -50,16 +50,4 @@ // This file is part of ICU4X. For terms of use, please see the file

group4.bench_function("TinyAsciiStr<4>", cfu!(TinyAsciiStr<4>, STRINGS_4));
group4.bench_function(
"tinystr_old::TinyStr4",
cfu!(tinystr_old::TinyStr4, STRINGS_4),
);
group4.bench_function("TinyAsciiStr<8>", cfu!(TinyAsciiStr<8>, STRINGS_4));
group4.bench_function(
"tinystr_old::TinyStr8",
cfu!(tinystr_old::TinyStr8, STRINGS_4),
);
group4.bench_function("TinyAsciiStr<16>", cfu!(TinyAsciiStr<16>, STRINGS_4));
group4.bench_function(
"tinystr_old::TinyStr16",
cfu!(tinystr_old::TinyStr16, STRINGS_4),
);
group4.finish();

@@ -69,11 +57,3 @@

group8.bench_function("TinyAsciiStr<8>", cfu!(TinyAsciiStr<8>, STRINGS_8));
group8.bench_function(
"tinystr_old::TinyStr8",
cfu!(tinystr_old::TinyStr8, STRINGS_8),
);
group8.bench_function("TinyAsciiStr<16>", cfu!(TinyAsciiStr<16>, STRINGS_8));
group8.bench_function(
"tinystr_old::TinyStr16",
cfu!(tinystr_old::TinyStr16, STRINGS_8),
);
group8.finish();

@@ -83,6 +63,2 @@

group16.bench_function("TinyAsciiStr<16>", cfu!(TinyAsciiStr<16>, STRINGS_16));
group16.bench_function(
"tinystr_old::TinyStr16",
cfu!(tinystr_old::TinyStr16, STRINGS_16),
);
group16.finish();

@@ -89,0 +65,0 @@ }

@@ -14,5 +14,2 @@ // This file is part of ICU4X. For terms of use, please see the file

use tinystr::TinyAsciiStr;
use tinystr_old::TinyStr16;
use tinystr_old::TinyStr4;
use tinystr_old::TinyStr8;

@@ -39,19 +36,2 @@ fn overview(c: &mut Criterion) {

g.bench_function("construct/TinyStr", |b| {
b.iter(|| {
for s in STRINGS_4 {
let _: TinyStr4 = black_box(s).parse().unwrap();
let _: TinyStr8 = black_box(s).parse().unwrap();
let _: TinyStr16 = black_box(s).parse().unwrap();
}
for s in STRINGS_8 {
let _: TinyStr8 = black_box(s).parse().unwrap();
let _: TinyStr16 = black_box(s).parse().unwrap();
}
for s in STRINGS_16 {
let _: TinyStr16 = black_box(s).parse().unwrap();
}
});
});
let parsed_ascii_4: Vec<TinyAsciiStr<4>> = STRINGS_4

@@ -73,18 +53,2 @@ .iter()

let parsed_tiny_4: Vec<TinyStr4> = STRINGS_4
.iter()
.map(|s| s.parse::<TinyStr4>().unwrap())
.collect();
let parsed_tiny_8: Vec<TinyStr8> = STRINGS_4
.iter()
.chain(STRINGS_8)
.map(|s| s.parse::<TinyStr8>().unwrap())
.collect();
let parsed_tiny_16: Vec<TinyStr16> = STRINGS_4
.iter()
.chain(STRINGS_8)
.chain(STRINGS_16)
.map(|s| s.parse::<TinyStr16>().unwrap())
.collect();
g.bench_function("read/TinyAsciiStr", |b| {

@@ -109,21 +73,2 @@ b.iter(|| {

g.bench_function("read/TinyStr", |b| {
b.iter(|| {
let mut collector: usize = 0;
for t in black_box(&parsed_tiny_4) {
let s: &str = t;
collector += s.bytes().map(usize::from).sum::<usize>();
}
for t in black_box(&parsed_tiny_8) {
let s: &str = t;
collector += s.bytes().map(usize::from).sum::<usize>();
}
for t in black_box(&parsed_tiny_16) {
let s: &str = t;
collector += s.bytes().map(usize::from).sum::<usize>();
}
collector
});
});
g.bench_function("compare/TinyAsciiStr", |b| {

@@ -147,21 +92,2 @@ b.iter(|| {

});
g.bench_function("compare/TinyStr", |b| {
b.iter(|| {
let mut collector: usize = 0;
for ts in black_box(&parsed_tiny_4).windows(2) {
let o = ts[0].cmp(&ts[1]);
collector ^= o as usize;
}
for ts in black_box(&parsed_tiny_8).windows(2) {
let o = ts[0].cmp(&ts[1]);
collector ^= o as usize;
}
for ts in black_box(&parsed_tiny_16).windows(2) {
let o = ts[0].cmp(&ts[1]);
collector ^= o as usize;
}
collector
});
});
}

@@ -168,0 +94,0 @@

@@ -14,6 +14,8 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO

edition = "2021"
rust-version = "1.66"
name = "tinystr"
version = "0.7.1"
version = "0.7.2"
authors = ["The ICU4X Project Developers"]
include = [
"data/**/*",
"src/**/*",

@@ -28,2 +30,3 @@ "examples/**/*",

description = "A small ASCII-only bounded length string representation."
readme = "README.md"
keywords = [

@@ -37,8 +40,7 @@ "string",

categories = ["data-structures"]
license = "Unicode-DFS-2016"
license-file = "LICENSE"
repository = "https://github.com/unicode-org/icu4x"
resolver = "2"
[package.metadata.workspaces]
independent = true
[package.metadata.cargo-all-features]
denylist = ["bench"]

@@ -48,5 +50,8 @@ [package.metadata.docs.rs]

[package.metadata.cargo-all-features]
denylist = ["bench"]
[package.metadata.workspaces]
independent = true
[lib]
bench = false
[[test]]

@@ -81,2 +86,3 @@ name = "serde"

optional = true
default-features = false

@@ -94,4 +100,5 @@ [dependencies.displaydoc]

[dependencies.zerovec]
version = "0.9.2"
version = "0.9.4"
optional = true
default-features = false

@@ -101,8 +108,6 @@ [dev-dependencies.bincode]

[dev-dependencies.criterion]
version = "0.3"
[dev-dependencies.postcard]
version = "1.0.0"
features = ["use-std"]
default-features = false

@@ -118,7 +123,2 @@ [dev-dependencies.rand]

[dev-dependencies.tinystr_old]
version = "0.4"
features = ["serde"]
package = "tinystr"
[features]

@@ -129,1 +129,4 @@ alloc = []

std = []
[target."cfg(not(target_arch = \"wasm32\"))".dev-dependencies.criterion]
version = "0.4"
+32
-39

@@ -1,47 +0,40 @@

UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
UNICODE LICENSE V3
See Terms of Use <https://www.unicode.org/copyright.html>
for definitions of Unicode Inc.’s Data Files and Software.
COPYRIGHT AND PERMISSION NOTICE
NOTICE TO USER: Carefully read the following legal agreement.
BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S
DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"),
YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
TERMS AND CONDITIONS OF THIS AGREEMENT.
IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE
THE DATA FILES OR SOFTWARE.
Copyright © 2020-2023 Unicode, Inc.
COPYRIGHT AND PERMISSION NOTICE
NOTICE TO USER: Carefully read the following legal agreement. BY
DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR
SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT
DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE.
Copyright © 1991-2022 Unicode, Inc. All rights reserved.
Distributed under the Terms of Use in https://www.unicode.org/copyright.html.
Permission is hereby granted, free of charge, to any person obtaining a
copy of data files and any associated documentation (the "Data Files") or
software and any associated documentation (the "Software") to deal in the
Data Files or Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, and/or sell
copies of the Data Files or Software, and to permit persons to whom the
Data Files or Software are furnished to do so, provided that either (a)
this copyright and permission notice appear with all copies of the Data
Files or Software, or (b) this copyright and permission notice appear in
associated Documentation.
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Unicode data files and any associated documentation
(the "Data Files") or Unicode software and any associated documentation
(the "Software") to deal in the Data Files or Software
without restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, and/or sell copies of
the Data Files or Software, and to permit persons to whom the Data Files
or Software are furnished to do so, provided that either
(a) this copyright and permission notice appear with all copies
of the Data Files or Software, or
(b) this copyright and permission notice appear in associated
Documentation.
THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
THIRD PARTY RIGHTS.
THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT OF THIRD PARTY RIGHTS.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THE DATA FILES OR SOFTWARE.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE
BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES,
OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA
FILES OR SOFTWARE.
Except as contained in this notice, the name of a copyright holder
shall not be used in advertising or otherwise to promote the sale,
use or other dealings in these Data Files or Software without prior
written authorization of the copyright holder.
Except as contained in this notice, the name of a copyright holder shall
not be used in advertising or otherwise to promote the sale, use or other
dealings in these Data Files or Software without prior written
authorization of the copyright holder.

@@ -48,0 +41,0 @@

# tinystr [![crates.io](https://img.shields.io/crates/v/tinystr)](https://crates.io/crates/tinystr)
<!-- cargo-rdme start -->
`tinystr` is a utility crate of the [`ICU4X`] project.

@@ -51,4 +53,6 @@

<!-- cargo-rdme end -->
## More Information
For more information on development, authorship, contributing etc. please visit [`ICU4X home page`](https://github.com/unicode-org/icu4x).

@@ -143,3 +143,5 @@ // This file is part of ICU4X. For terms of use, please see the file

// and changing the length of that slice to self.len() < N is safe.
unsafe { core::mem::transmute((self.bytes.as_slice().as_ptr(), self.len())) }
unsafe {
core::slice::from_raw_parts(self.bytes.as_slice().as_ptr() as *const u8, self.len())
}
}

@@ -151,3 +153,3 @@

// SAFETY: `self.bytes` has same size as [u8; N]
unsafe { core::mem::transmute(&self.bytes) }
unsafe { &*(self.bytes.as_ptr() as *const [u8; N]) }
}

@@ -157,5 +159,5 @@

#[must_use]
/// Resizes a TinyAsciiStr<N> to a TinyAsciiStr<M>.
/// Resizes a `TinyAsciiStr<N>` to a `TinyAsciiStr<M>`.
///
/// If M < len() the string gets truncated, otherwise only the
/// If `M < len()` the string gets truncated, otherwise only the
/// memory representation changes.

@@ -735,3 +737,3 @@ pub const fn resize<const M: usize>(self) -> TinyAsciiStr<M> {

let actual = tinystr_f(t);
assert_eq!(expected, actual, "TinyAsciiStr<{}>: {:?}", N, s);
assert_eq!(expected, actual, "TinyAsciiStr<{N}>: {s:?}");
}

@@ -738,0 +740,0 @@ }

@@ -6,2 +6,3 @@ // This file is part of ICU4X. For terms of use, please see the file

use crate::TinyAsciiStr;
use crate::UnvalidatedTinyAsciiStr;
use databake::*;

@@ -14,3 +15,3 @@

quote! {
::tinystr::tinystr!(#N, #string)
tinystr::tinystr!(#N, #string)
}

@@ -20,2 +21,22 @@ }

impl<const N: usize> databake::Bake for UnvalidatedTinyAsciiStr<N> {
fn bake(&self, env: &databake::CrateEnv) -> databake::TokenStream {
match self.try_into_tinystr() {
Ok(tiny) => {
let tiny = tiny.bake(env);
databake::quote! {
#tiny.to_unvalidated()
}
}
Err(_) => {
let bytes = self.0.bake(env);
env.insert("tinystr");
databake::quote! {
tinystr::UnvalidatedTinyAsciiStr::from_bytes_unchecked(*#bytes)
}
}
}
}
}
#[test]

@@ -25,1 +46,7 @@ fn test() {

}
#[test]
fn test_unvalidated() {
test_bake!(UnvalidatedTinyAsciiStr<10>, const: crate::tinystr!(10usize, "foo").to_unvalidated(), tinystr);
test_bake!(UnvalidatedTinyAsciiStr<3>, const: crate::UnvalidatedTinyAsciiStr::from_bytes_unchecked(*b"AB\xCD"), tinystr);
}

@@ -75,2 +75,3 @@ // This file is part of ICU4X. For terms of use, please see the file

mod int_ops;
mod unvalidated;

@@ -91,2 +92,3 @@ #[cfg(feature = "serde")]

pub use error::TinyStrError;
pub use unvalidated::UnvalidatedTinyAsciiStr;

@@ -93,0 +95,0 @@ /// These are temporary compatability reexports that will be removed

@@ -49,3 +49,3 @@ // This file is part of ICU4X. For terms of use, please see the file

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "a TinyAsciiStr<{}>", N)
write!(formatter, "a TinyAsciiStr<{N}>")
}

@@ -52,0 +52,0 @@

@@ -5,3 +5,3 @@ // This file is part of ICU4X. For terms of use, please see the file

use crate::TinyAsciiStr;
use crate::{TinyAsciiStr, UnvalidatedTinyAsciiStr};
use zerovec::maps::ZeroMapKV;

@@ -12,5 +12,5 @@ use zerovec::ule::*;

// Safety (based on the safety checklist on the ULE trait):
// 1. CharULE does not include any uninitialized or padding bytes.
// 1. TinyAsciiStr does not include any uninitialized or padding bytes.
// (achieved by `#[repr(transparent)]` on a type that satisfies this invariant)
// 2. CharULE is aligned to 1 byte.
// 2. TinyAsciiStr is aligned to 1 byte.
// (achieved by `#[repr(transparent)]` on a type that satisfies this invariant)

@@ -20,3 +20,3 @@ // 3. The impl of validate_byte_slice() returns an error if any byte is not valid.

// 5. The other ULE methods use the default impl.
// 6. CharULE byte equality is semantic equality
// 6. TinyAsciiStr byte equality is semantic equality
unsafe impl<const N: usize> ULE for TinyAsciiStr<N> {

@@ -58,2 +58,42 @@ #[inline]

// Safety (based on the safety checklist on the ULE trait):
// 1. UnvalidatedTinyAsciiStr does not include any uninitialized or padding bytes.
// (achieved by `#[repr(transparent)]` on a type that satisfies this invariant)
// 2. UnvalidatedTinyAsciiStr is aligned to 1 byte.
// (achieved by `#[repr(transparent)]` on a type that satisfies this invariant)
// 3. The impl of validate_byte_slice() returns an error if any byte is not valid.
// 4. The impl of validate_byte_slice() returns an error if there are extra bytes.
// 5. The other ULE methods use the default impl.
// 6. UnvalidatedTinyAsciiStr byte equality is semantic equality
unsafe impl<const N: usize> ULE for UnvalidatedTinyAsciiStr<N> {
#[inline]
fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> {
if bytes.len() % N != 0 {
return Err(ZeroVecError::length::<Self>(bytes.len()));
}
Ok(())
}
}
impl<const N: usize> AsULE for UnvalidatedTinyAsciiStr<N> {
type ULE = Self;
#[inline]
fn to_unaligned(self) -> Self::ULE {
self
}
#[inline]
fn from_unaligned(unaligned: Self::ULE) -> Self {
unaligned
}
}
impl<'a, const N: usize> ZeroMapKV<'a> for UnvalidatedTinyAsciiStr<N> {
type Container = ZeroVec<'a, UnvalidatedTinyAsciiStr<N>>;
type Slice = ZeroSlice<UnvalidatedTinyAsciiStr<N>>;
type GetType = UnvalidatedTinyAsciiStr<N>;
type OwnedType = UnvalidatedTinyAsciiStr<N>;
}
#[cfg(test)]

@@ -60,0 +100,0 @@ mod test {

Sorry, the diff of this file is not supported yet