| { | ||
| "git": { | ||
| "sha1": "29dfe2790b6cfdab94ca6a6b69f58ce54802dbf7" | ||
| "sha1": "c9fac4e625ccb2c6a7aa35079fff9709db4385ac" | ||
| }, | ||
| "path_in_vcs": "utils/tinystr" | ||
| } |
+67
-87
@@ -7,5 +7,5 @@ # This file is automatically @generated by Cargo. | ||
| name = "aho-corasick" | ||
| version = "1.1.3" | ||
| version = "1.1.4" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" | ||
| checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" | ||
| dependencies = [ | ||
@@ -23,5 +23,5 @@ "memchr", | ||
| name = "anstyle" | ||
| version = "1.0.13" | ||
| version = "1.0.14" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" | ||
| checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" | ||
@@ -45,5 +45,5 @@ [[package]] | ||
| name = "bumpalo" | ||
| version = "3.19.0" | ||
| version = "3.20.2" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" | ||
| checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" | ||
@@ -192,5 +192,5 @@ [[package]] | ||
| name = "databake" | ||
| version = "0.2.0" | ||
| version = "0.2.1" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "ff6ee9e2d2afb173bcdeee45934c89ec341ab26f91c9933774fc15c2b58f83ef" | ||
| checksum = "74d4b1db5ca40636726f1f73daff0d626accbd49bcd8136fcade87d7cf1e6bbb" | ||
| dependencies = [ | ||
@@ -280,11 +280,11 @@ "proc-macro2", | ||
| name = "itoa" | ||
| version = "1.0.15" | ||
| version = "1.0.18" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" | ||
| checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" | ||
| [[package]] | ||
| name = "js-sys" | ||
| version = "0.3.81" | ||
| version = "0.3.91" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" | ||
| checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c" | ||
| dependencies = [ | ||
@@ -297,17 +297,11 @@ "once_cell", | ||
| name = "libc" | ||
| version = "0.2.177" | ||
| version = "0.2.183" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" | ||
| checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" | ||
| [[package]] | ||
| name = "log" | ||
| version = "0.4.28" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" | ||
| [[package]] | ||
| name = "memchr" | ||
| version = "2.7.6" | ||
| version = "2.8.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" | ||
| checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" | ||
@@ -325,5 +319,5 @@ [[package]] | ||
| name = "once_cell" | ||
| version = "1.21.3" | ||
| version = "1.21.4" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" | ||
| checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" | ||
@@ -387,5 +381,5 @@ [[package]] | ||
| name = "proc-macro2" | ||
| version = "1.0.103" | ||
| version = "1.0.106" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" | ||
| checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" | ||
| dependencies = [ | ||
@@ -397,5 +391,5 @@ "unicode-ident", | ||
| name = "quote" | ||
| version = "1.0.41" | ||
| version = "1.0.45" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" | ||
| checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" | ||
| dependencies = [ | ||
@@ -433,5 +427,5 @@ "proc-macro2", | ||
| name = "rand_core" | ||
| version = "0.9.3" | ||
| version = "0.9.5" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" | ||
| checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" | ||
| dependencies = [ | ||
@@ -463,5 +457,5 @@ "getrandom", | ||
| name = "regex" | ||
| version = "1.12.2" | ||
| version = "1.12.3" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" | ||
| checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" | ||
| dependencies = [ | ||
@@ -476,5 +470,5 @@ "aho-corasick", | ||
| name = "regex-automata" | ||
| version = "0.4.13" | ||
| version = "0.4.14" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" | ||
| checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" | ||
| dependencies = [ | ||
@@ -488,5 +482,5 @@ "aho-corasick", | ||
| name = "regex-syntax" | ||
| version = "0.8.8" | ||
| version = "0.8.10" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" | ||
| checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" | ||
@@ -500,8 +494,2 @@ [[package]] | ||
| [[package]] | ||
| name = "ryu" | ||
| version = "1.0.20" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" | ||
| [[package]] | ||
| name = "same-file" | ||
@@ -547,11 +535,11 @@ version = "1.0.6" | ||
| name = "serde_json" | ||
| version = "1.0.145" | ||
| version = "1.0.149" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" | ||
| checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" | ||
| dependencies = [ | ||
| "itoa", | ||
| "memchr", | ||
| "ryu", | ||
| "serde", | ||
| "serde_core", | ||
| "zmij", | ||
| ] | ||
@@ -561,5 +549,5 @@ | ||
| name = "syn" | ||
| version = "2.0.108" | ||
| version = "2.0.117" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917" | ||
| checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" | ||
| dependencies = [ | ||
@@ -573,5 +561,5 @@ "proc-macro2", | ||
| name = "thiserror" | ||
| version = "2.0.17" | ||
| version = "2.0.18" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" | ||
| checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" | ||
| dependencies = [ | ||
@@ -583,5 +571,5 @@ "thiserror-impl", | ||
| name = "thiserror-impl" | ||
| version = "2.0.17" | ||
| version = "2.0.18" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" | ||
| checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" | ||
| dependencies = [ | ||
@@ -595,3 +583,3 @@ "proc-macro2", | ||
| name = "tinystr" | ||
| version = "0.8.2" | ||
| version = "0.8.3" | ||
| dependencies = [ | ||
@@ -621,5 +609,5 @@ "bincode", | ||
| name = "unicode-ident" | ||
| version = "1.0.20" | ||
| version = "1.0.24" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06" | ||
| checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" | ||
@@ -647,5 +635,5 @@ [[package]] | ||
| name = "wasm-bindgen" | ||
| version = "0.2.104" | ||
| version = "0.2.114" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" | ||
| checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e" | ||
| dependencies = [ | ||
@@ -660,20 +648,6 @@ "cfg-if", | ||
| [[package]] | ||
| name = "wasm-bindgen-backend" | ||
| version = "0.2.104" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" | ||
| dependencies = [ | ||
| "bumpalo", | ||
| "log", | ||
| "proc-macro2", | ||
| "quote", | ||
| "syn", | ||
| "wasm-bindgen-shared", | ||
| ] | ||
| [[package]] | ||
| name = "wasm-bindgen-macro" | ||
| version = "0.2.104" | ||
| version = "0.2.114" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" | ||
| checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6" | ||
| dependencies = [ | ||
@@ -686,10 +660,10 @@ "quote", | ||
| name = "wasm-bindgen-macro-support" | ||
| version = "0.2.104" | ||
| version = "0.2.114" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" | ||
| checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3" | ||
| dependencies = [ | ||
| "bumpalo", | ||
| "proc-macro2", | ||
| "quote", | ||
| "syn", | ||
| "wasm-bindgen-backend", | ||
| "wasm-bindgen-shared", | ||
@@ -700,5 +674,5 @@ ] | ||
| name = "wasm-bindgen-shared" | ||
| version = "0.2.104" | ||
| version = "0.2.114" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" | ||
| checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16" | ||
| dependencies = [ | ||
@@ -710,5 +684,5 @@ "unicode-ident", | ||
| name = "web-sys" | ||
| version = "0.3.81" | ||
| version = "0.3.91" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120" | ||
| checksum = "854ba17bb104abfb26ba36da9729addc7ce7f06f5c0f90f3c391f8461cca21f9" | ||
| dependencies = [ | ||
@@ -751,5 +725,5 @@ "js-sys", | ||
| name = "zerocopy" | ||
| version = "0.8.27" | ||
| version = "0.8.47" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" | ||
| checksum = "efbb2a062be311f2ba113ce66f697a4dc589f85e78a4aea276200804cea0ed87" | ||
| dependencies = [ | ||
@@ -761,5 +735,5 @@ "zerocopy-derive", | ||
| name = "zerocopy-derive" | ||
| version = "0.8.27" | ||
| version = "0.8.47" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" | ||
| checksum = "0e8bc7269b54418e7aeeef514aa68f8690b8c0489a06b0136e5f57c4c5ccab89" | ||
| dependencies = [ | ||
@@ -773,11 +747,11 @@ "proc-macro2", | ||
| name = "zerofrom" | ||
| version = "0.1.6" | ||
| version = "0.1.7" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" | ||
| checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" | ||
| [[package]] | ||
| name = "zerovec" | ||
| version = "0.11.5" | ||
| version = "0.11.6" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" | ||
| checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" | ||
| dependencies = [ | ||
@@ -787,1 +761,7 @@ "serde", | ||
| ] | ||
| [[package]] | ||
| name = "zmij" | ||
| version = "1.0.21" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" |
+56
-5
@@ -16,3 +16,3 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO | ||
| name = "tinystr" | ||
| version = "0.8.2" | ||
| version = "0.8.3" | ||
| authors = ["The ICU4X Project Developers"] | ||
@@ -39,7 +39,6 @@ build = false | ||
| keywords = [ | ||
| "small-string", | ||
| "ascii", | ||
| "string", | ||
| "str", | ||
| "small", | ||
| "tiny", | ||
| "no_std", | ||
| ] | ||
@@ -56,2 +55,5 @@ categories = ["data-structures"] | ||
| [package.metadata.cargo-all-features] | ||
| max_combination_size = 3 | ||
| [features] | ||
@@ -114,3 +116,3 @@ alloc = [ | ||
| [dependencies.zerovec] | ||
| version = "0.11.3" | ||
| version = "0.11.6" | ||
| optional = true | ||
@@ -137,1 +139,50 @@ default-features = false | ||
| version = "0.5.0" | ||
| [lints.clippy] | ||
| alloc-instead-of-core = "warn" | ||
| branches-sharing-code = "warn" | ||
| collection_is_never_read = "warn" | ||
| crosspointer_transmute = "warn" | ||
| dbg_macro = "warn" | ||
| debug_assert_with_mut_call = "warn" | ||
| doc_markdown = "warn" | ||
| exhaustive_enums = "deny" | ||
| exhaustive_structs = "deny" | ||
| fn_to_numeric_cast_any = "warn" | ||
| infinite_loop = "warn" | ||
| large_stack_arrays = "warn" | ||
| mismatching_type_param_order = "warn" | ||
| missing_fields_in_debug = "warn" | ||
| missing_transmute_annotations = "warn" | ||
| negative_feature_names = "warn" | ||
| or-fun-call = "warn" | ||
| same_functions_in_if_condition = "warn" | ||
| todo = "warn" | ||
| transmute_bytes_to_str = "warn" | ||
| transmute_int_to_bool = "warn" | ||
| transmute_int_to_non_zero = "warn" | ||
| transmute_ptr_to_ptr = "warn" | ||
| transmute_ptr_to_ref = "warn" | ||
| transmute_undefined_repr = "warn" | ||
| transmutes_expressible_as_ptr_casts = "warn" | ||
| trivially_copy_pass_by_ref = "deny" | ||
| unnecessary-wraps = "warn" | ||
| useless_transmute = "warn" | ||
| wildcard_dependencies = "warn" | ||
| [lints.rust] | ||
| missing_debug_implementations = "deny" | ||
| trivial_numeric_casts = "deny" | ||
| unused_lifetimes = "warn" | ||
| unused_macro_rules = "warn" | ||
| unused_qualifications = "warn" | ||
| [lints.rust.unexpected_cfgs] | ||
| level = "warn" | ||
| priority = 0 | ||
| check-cfg = [ | ||
| "cfg(icu4c_enable_renaming)", | ||
| "cfg(needs_alloc_error_handler)", | ||
| "cfg(icu4x_run_size_tests)", | ||
| "cfg(icu4x_unstable_fast_trie_only)", | ||
| ] |
+55
-18
@@ -8,2 +8,4 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| use crate::ParseError; | ||
| #[cfg(feature = "alloc")] | ||
| use alloc::string::String; | ||
| use core::borrow::Borrow; | ||
@@ -21,2 +23,7 @@ use core::fmt; | ||
| impl<const N: usize> TinyAsciiStr<N> { | ||
| /// The empty string. | ||
| pub const EMPTY: Self = Self { | ||
| bytes: [AsciiByte::B0; N], | ||
| }; | ||
| #[inline] | ||
@@ -44,7 +51,15 @@ pub const fn try_from_str(s: &str) -> Result<Self, ParseError> { | ||
| /// Invalid code units, as well as null or non-ASCII code points | ||
| /// (i.e. those outside the range U+0001..=U+007F`) | ||
| /// (i.e. those outside the range `U+0001..=U+007F`) | ||
| /// will be replaced with the replacement byte. | ||
| /// | ||
| /// The input slice will be truncated if its length exceeds `N`. | ||
| /// | ||
| /// # Panics | ||
| /// | ||
| /// Panics if `replacement` is not a non-null ASCII byte (i.e. not in `1..=127`). | ||
| pub const fn from_utf8_lossy(code_units: &[u8], replacement: u8) -> Self { | ||
| assert!( | ||
| replacement > 0 && replacement < 0x80, | ||
| "replacement must be a non-null ASCII byte (1..=127)" | ||
| ); | ||
| let mut out = [0; N]; | ||
@@ -80,7 +95,15 @@ let mut i = 0; | ||
| /// Invalid code units, as well as null or non-ASCII code points | ||
| /// (i.e. those outside the range U+0001..=U+007F`) | ||
| /// (i.e. those outside the range `U+0001..=U+007F`) | ||
| /// will be replaced with the replacement byte. | ||
| /// | ||
| /// The input slice will be truncated if its length exceeds `N`. | ||
| /// | ||
| /// # Panics | ||
| /// | ||
| /// Panics if `replacement` is not a non-null ASCII byte (i.e. not in `1..=127`). | ||
| pub const fn from_utf16_lossy(code_units: &[u16], replacement: u8) -> Self { | ||
| assert!( | ||
| replacement > 0 && replacement < 0x80, | ||
| "replacement must be a non-null ASCII byte (1..=127)" | ||
| ); | ||
| let mut out = [0; N]; | ||
@@ -716,3 +739,3 @@ let mut i = 0; | ||
| if N <= 4 { | ||
| let aligned = Aligned4::from_ascii_bytes(&$self.bytes).$to().to_ascii_bytes(); | ||
| let aligned = Aligned4::from_ascii_bytes(&$self.bytes).$to(); | ||
| // Won't panic because self.bytes has length N and aligned has length >= N | ||
@@ -725,3 +748,3 @@ #[expect(clippy::indexing_slicing)] | ||
| } else if N <= 8 { | ||
| let aligned = Aligned8::from_ascii_bytes(&$self.bytes).$to().to_ascii_bytes(); | ||
| let aligned = Aligned8::from_ascii_bytes(&$self.bytes).$to(); | ||
| // Won't panic because self.bytes has length N and aligned has length >= N | ||
@@ -735,15 +758,7 @@ #[expect(clippy::indexing_slicing)] | ||
| while i < N && $self.bytes[i] as u8 != AsciiByte::B0 as u8 { | ||
| // SAFETY: AsciiByte is repr(u8) and has same size as u8 | ||
| unsafe { | ||
| $self.bytes[i] = core::mem::transmute::<u8, AsciiByte>( | ||
| ($self.bytes[i] as u8).$later_char_to() | ||
| ); | ||
| } | ||
| $self.bytes[i] = $self.bytes[i].$later_char_to(); | ||
| i += 1; | ||
| } | ||
| // SAFETY: AsciiByte is repr(u8) and has same size as u8 | ||
| $( | ||
| $self.bytes[0] = unsafe { | ||
| core::mem::transmute::<u8, AsciiByte>(($self.bytes[0] as u8).$first_char_to()) | ||
| }; | ||
| $self.bytes[0] = $self.bytes[0].$first_char_to(); | ||
| )? | ||
@@ -868,4 +883,4 @@ } | ||
| #[cfg(feature = "alloc")] | ||
| impl<const N: usize> PartialEq<alloc::string::String> for TinyAsciiStr<N> { | ||
| fn eq(&self, other: &alloc::string::String) -> bool { | ||
| impl<const N: usize> PartialEq<String> for TinyAsciiStr<N> { | ||
| fn eq(&self, other: &String) -> bool { | ||
| self.deref() == other.deref() | ||
@@ -876,3 +891,3 @@ } | ||
| #[cfg(feature = "alloc")] | ||
| impl<const N: usize> PartialEq<TinyAsciiStr<N>> for alloc::string::String { | ||
| impl<const N: usize> PartialEq<TinyAsciiStr<N>> for String { | ||
| fn eq(&self, other: &TinyAsciiStr<N>) -> bool { | ||
@@ -944,3 +959,3 @@ self.deref() == other.deref() | ||
| F2: Fn(TinyAsciiStr<N>) -> T, | ||
| T: core::fmt::Debug + core::cmp::PartialEq, | ||
| T: fmt::Debug + PartialEq, | ||
| { | ||
@@ -1240,2 +1255,24 @@ for s in STRINGS | ||
| } | ||
| #[test] | ||
| #[should_panic(expected = "replacement must be a non-null ASCII byte")] | ||
| fn from_utf8_lossy_rejects_non_ascii_replacement() { | ||
| // A non-ASCII replacement byte (>= 0x80) would create an invalid AsciiByte | ||
| // discriminant and then from_utf8_unchecked would be called on non-UTF-8 | ||
| // data (UB). The fix validates the replacement byte on entry. | ||
| let _ = TinyAsciiStr::<4>::from_utf8_lossy(b"\xFF", 0xFF); | ||
| } | ||
| #[test] | ||
| #[should_panic(expected = "replacement must be a non-null ASCII byte")] | ||
| fn from_utf16_lossy_rejects_non_ascii_replacement() { | ||
| let _ = TinyAsciiStr::<4>::from_utf16_lossy(&[0xFFFF], 0xFF); | ||
| } | ||
| #[test] | ||
| #[should_panic(expected = "replacement must be a non-null ASCII byte")] | ||
| fn from_utf8_lossy_rejects_null_replacement() { | ||
| // Null (0x00) is also invalid — it's the TinyAsciiStr terminator. | ||
| let _ = TinyAsciiStr::<4>::from_utf8_lossy(b"\xFF", 0x00); | ||
| } | ||
| } |
+12
-1
@@ -140,3 +140,3 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| impl AsciiByte { | ||
| /// Convert [u8; N] to [AsciiByte; N] | ||
| /// Convert `[u8; N]` to `[AsciiByte; N]` | ||
| /// | ||
@@ -171,2 +171,13 @@ /// # Safety | ||
| } | ||
| #[inline] | ||
| pub(crate) const fn to_ascii_uppercase(self) -> Self { | ||
| // SAFETY: AsciiByte is repr(u8) and has same size as u8 | ||
| unsafe { core::mem::transmute::<u8, AsciiByte>((self as u8).to_ascii_uppercase()) } | ||
| } | ||
| pub(crate) const fn to_ascii_lowercase(self) -> Self { | ||
| // SAFETY: AsciiByte is repr(u8) and has same size as u8 | ||
| unsafe { core::mem::transmute::<u8, AsciiByte>((self as u8).to_ascii_lowercase()) } | ||
| } | ||
| } |
+5
-5
@@ -25,8 +25,8 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| impl<const N: usize> databake::Bake for UnvalidatedTinyAsciiStr<N> { | ||
| fn bake(&self, env: &databake::CrateEnv) -> databake::TokenStream { | ||
| impl<const N: usize> Bake for UnvalidatedTinyAsciiStr<N> { | ||
| fn bake(&self, env: &CrateEnv) -> TokenStream { | ||
| match self.try_into_tinystr() { | ||
| Ok(tiny) => { | ||
| let tiny = tiny.bake(env); | ||
| databake::quote! { | ||
| quote! { | ||
| #tiny.to_unvalidated() | ||
@@ -38,3 +38,3 @@ } | ||
| env.insert("tinystr"); | ||
| databake::quote! { | ||
| quote! { | ||
| tinystr::UnvalidatedTinyAsciiStr::from_utf8_unchecked(#bytes) | ||
@@ -47,3 +47,3 @@ } | ||
| impl<const N: usize> databake::BakeSize for UnvalidatedTinyAsciiStr<N> { | ||
| impl<const N: usize> BakeSize for UnvalidatedTinyAsciiStr<N> { | ||
| fn borrows_size(&self) -> usize { | ||
@@ -50,0 +50,0 @@ 0 |
+16
-46
@@ -16,3 +16,3 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| #[inline] | ||
| pub const fn from_utf8<const N: usize>(src: &[u8; N]) -> Self { | ||
| pub const fn from_ascii_bytes<const N: usize>(src: &[AsciiByte; N]) -> Self { | ||
| let mut bytes = [0; 4]; | ||
@@ -23,3 +23,3 @@ let mut i = 0; | ||
| while i < N { | ||
| bytes[i] = src[i]; | ||
| bytes[i] = src[i] as u8; | ||
| i += 1; | ||
@@ -30,17 +30,2 @@ } | ||
| #[inline] | ||
| pub const fn from_ascii_bytes<const N: usize>(src: &[AsciiByte; N]) -> Self { | ||
| Self::from_utf8::<N>(unsafe { core::mem::transmute::<&[AsciiByte; N], &[u8; N]>(src) }) | ||
| } | ||
| #[inline] | ||
| pub const fn to_bytes(&self) -> [u8; 4] { | ||
| self.0.to_ne_bytes() | ||
| } | ||
| #[inline] | ||
| pub const fn to_ascii_bytes(&self) -> [AsciiByte; 4] { | ||
| unsafe { core::mem::transmute(self.to_bytes()) } | ||
| } | ||
| pub const fn len(&self) -> usize { | ||
@@ -147,19 +132,19 @@ let word = self.0; | ||
| pub const fn to_ascii_lowercase(&self) -> Self { | ||
| pub const fn to_ascii_lowercase(&self) -> [AsciiByte; 4] { | ||
| let word = self.0; | ||
| let result = word | (((word + 0x3f3f_3f3f) & !(word + 0x2525_2525) & 0x8080_8080) >> 2); | ||
| Self(result) | ||
| unsafe { AsciiByte::to_ascii_byte_array(&result.to_ne_bytes()) } | ||
| } | ||
| pub const fn to_ascii_titlecase(&self) -> Self { | ||
| pub const fn to_ascii_titlecase(&self) -> [AsciiByte; 4] { | ||
| let word = self.0.to_le(); | ||
| let mask = ((word + 0x3f3f_3f1f) & !(word + 0x2525_2505) & 0x8080_8080) >> 2; | ||
| let result = (word | mask) & !(0x20 & mask); | ||
| Self(u32::from_le(result)) | ||
| unsafe { AsciiByte::to_ascii_byte_array(&u32::from_le(result).to_ne_bytes()) } | ||
| } | ||
| pub const fn to_ascii_uppercase(&self) -> Self { | ||
| pub const fn to_ascii_uppercase(&self) -> [AsciiByte; 4] { | ||
| let word = self.0; | ||
| let result = word & !(((word + 0x1f1f_1f1f) & !(word + 0x0505_0505) & 0x8080_8080) >> 2); | ||
| Self(result) | ||
| unsafe { AsciiByte::to_ascii_byte_array(&result.to_ne_bytes()) } | ||
| } | ||
@@ -177,3 +162,3 @@ } | ||
| #[inline] | ||
| pub const fn from_utf8<const N: usize>(src: &[u8; N]) -> Self { | ||
| pub const fn from_ascii_bytes<const N: usize>(src: &[AsciiByte; N]) -> Self { | ||
| let mut bytes = [0; 8]; | ||
@@ -184,3 +169,3 @@ let mut i = 0; | ||
| while i < N { | ||
| bytes[i] = src[i]; | ||
| bytes[i] = src[i] as u8; | ||
| i += 1; | ||
@@ -191,17 +176,2 @@ } | ||
| #[inline] | ||
| pub const fn from_ascii_bytes<const N: usize>(src: &[AsciiByte; N]) -> Self { | ||
| Self::from_utf8::<N>(unsafe { core::mem::transmute::<&[AsciiByte; N], &[u8; N]>(src) }) | ||
| } | ||
| #[inline] | ||
| pub const fn to_bytes(&self) -> [u8; 8] { | ||
| self.0.to_ne_bytes() | ||
| } | ||
| #[inline] | ||
| pub const fn to_ascii_bytes(&self) -> [AsciiByte; 8] { | ||
| unsafe { core::mem::transmute(self.to_bytes()) } | ||
| } | ||
| pub const fn len(&self) -> usize { | ||
@@ -293,3 +263,3 @@ let word = self.0; | ||
| pub const fn to_ascii_lowercase(&self) -> Self { | ||
| pub const fn to_ascii_lowercase(&self) -> [AsciiByte; 8] { | ||
| let word = self.0; | ||
@@ -301,6 +271,6 @@ let result = word | ||
| >> 2); | ||
| Self(result) | ||
| unsafe { AsciiByte::to_ascii_byte_array(&result.to_ne_bytes()) } | ||
| } | ||
| pub const fn to_ascii_titlecase(&self) -> Self { | ||
| pub const fn to_ascii_titlecase(&self) -> [AsciiByte; 8] { | ||
| let word = self.0.to_le(); | ||
@@ -312,6 +282,6 @@ let mask = ((word + 0x3f3f_3f3f_3f3f_3f1f) | ||
| let result = (word | mask) & !(0x20 & mask); | ||
| Self(u64::from_le(result)) | ||
| unsafe { AsciiByte::to_ascii_byte_array(&u64::from_le(result).to_ne_bytes()) } | ||
| } | ||
| pub const fn to_ascii_uppercase(&self) -> Self { | ||
| pub const fn to_ascii_uppercase(&self) -> [AsciiByte; 8] { | ||
| let word = self.0; | ||
@@ -323,4 +293,4 @@ let result = word | ||
| >> 2); | ||
| Self(result) | ||
| unsafe { AsciiByte::to_ascii_byte_array(&result.to_ne_bytes()) } | ||
| } | ||
| } |
+15
-24
@@ -5,2 +5,15 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| // https://github.com/unicode-org/icu4x/blob/main/documents/process/boilerplate.md#library-annotations | ||
| #![cfg_attr(not(any(test, doc)), no_std)] | ||
| #![cfg_attr( | ||
| not(test), | ||
| deny( | ||
| clippy::indexing_slicing, | ||
| clippy::unwrap_used, | ||
| clippy::expect_used, | ||
| clippy::panic, | ||
| ) | ||
| )] | ||
| // #![warn(missing_docs)] | ||
| //! `tinystr` is a utility crate of the [`ICU4X`] project. | ||
@@ -55,18 +68,2 @@ //! | ||
| // https://github.com/unicode-org/icu4x/blob/main/documents/process/boilerplate.md#library-annotations | ||
| #![cfg_attr(not(any(test, doc)), no_std)] | ||
| #![cfg_attr( | ||
| not(test), | ||
| deny( | ||
| clippy::indexing_slicing, | ||
| clippy::unwrap_used, | ||
| clippy::expect_used, | ||
| clippy::panic, | ||
| clippy::exhaustive_structs, | ||
| clippy::exhaustive_enums, | ||
| clippy::trivially_copy_pass_by_ref, | ||
| missing_debug_implementations, | ||
| ) | ||
| )] | ||
| mod macros; | ||
@@ -108,10 +105,4 @@ | ||
| fn test_size() { | ||
| assert_eq!( | ||
| core::mem::size_of::<TinyStr4>(), | ||
| core::mem::size_of::<Option<TinyStr4>>() | ||
| ); | ||
| assert_eq!( | ||
| core::mem::size_of::<TinyStr8>(), | ||
| core::mem::size_of::<Option<TinyStr8>>() | ||
| ); | ||
| assert_eq!(size_of::<TinyStr4>(), size_of::<Option<TinyStr4>>()); | ||
| assert_eq!(size_of::<TinyStr8>(), size_of::<Option<TinyStr8>>()); | ||
| } |
+16
-1
@@ -37,3 +37,18 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| #[inline] | ||
| /// Unsafely converts into a [`TinyAsciiStr`]. | ||
| /// Creates one of these from a byte slice. Fails if the bytes are too long, but | ||
| /// does not check whether the bytes are a valid ASCII string. | ||
| pub fn try_from_utf8(bytes: &[u8]) -> Result<Self, ParseError> { | ||
| if bytes.len() > N { | ||
| return Err(ParseError::TooLong { | ||
| max: N, | ||
| len: bytes.len(), | ||
| }); | ||
| } | ||
| let mut target = [0u8; N]; | ||
| target[0..bytes.len()].copy_from_slice(bytes); | ||
| Ok(Self(target)) | ||
| } | ||
| #[inline] | ||
| /// Creates one of these from a raw byte array. | ||
| pub const fn from_utf8_unchecked(bytes: [u8; N]) -> Self { | ||
@@ -40,0 +55,0 @@ Self(bytes) |
Sorry, the diff of this file is not supported yet