diff options
| author | mo khan <mo@mokhan.ca> | 2025-07-15 16:37:08 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2025-07-17 16:30:22 -0600 |
| commit | 45df4d0d9b577fecee798d672695fe24ff57fb1b (patch) | |
| tree | 1b99bf645035b58e0d6db08c7a83521f41f7a75b /vendor/potential_utf/src | |
| parent | f94f79608393d4ab127db63cc41668445ef6b243 (diff) | |
feat: migrate from Cedar to SpiceDB authorization system
This is a major architectural change that replaces the Cedar policy-based
authorization system with SpiceDB's relation-based authorization.
Key changes:
- Migrate from Rust to Go implementation
- Replace Cedar policies with SpiceDB schema and relationships
- Switch from envoy `ext_authz` with Cedar to SpiceDB permission checks
- Update build system and dependencies for Go ecosystem
- Maintain Envoy integration for external authorization
This change enables more flexible permission modeling through SpiceDB's
Google Zanzibar inspired relation-based system, supporting complex
hierarchical permissions that were difficult to express in Cedar.
Breaking change: Existing Cedar policies and Rust-based configuration
will no longer work and need to be migrated to SpiceDB schema.
Diffstat (limited to 'vendor/potential_utf/src')
| -rw-r--r-- | vendor/potential_utf/src/lib.rs | 33 | ||||
| -rw-r--r-- | vendor/potential_utf/src/uchar.rs | 375 | ||||
| -rw-r--r-- | vendor/potential_utf/src/ustr.rs | 270 | ||||
| -rw-r--r-- | vendor/potential_utf/src/writeable.rs | 159 |
4 files changed, 0 insertions, 837 deletions
diff --git a/vendor/potential_utf/src/lib.rs b/vendor/potential_utf/src/lib.rs deleted file mode 100644 index 2b343c9c..00000000 --- a/vendor/potential_utf/src/lib.rs +++ /dev/null @@ -1,33 +0,0 @@ -// 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 ). - -#![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, - ) -)] - -//! A crate providing unvalidated string and character types. - -#[cfg(feature = "alloc")] -extern crate alloc; - -mod uchar; -mod ustr; - -pub use uchar::PotentialCodePoint; -pub use ustr::PotentialUtf16; -pub use ustr::PotentialUtf8; - -#[cfg(feature = "writeable")] -mod writeable; diff --git a/vendor/potential_utf/src/uchar.rs b/vendor/potential_utf/src/uchar.rs deleted file mode 100644 index 280964ca..00000000 --- a/vendor/potential_utf/src/uchar.rs +++ /dev/null @@ -1,375 +0,0 @@ -// 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 core::cmp::Ordering; -use core::fmt; - -/// A 24-bit numeric data type that is expected to be a Unicode scalar value, but is not -/// validated as such. -/// -/// Use this type instead of `char` when you want to deal with data that is expected to be valid -/// Unicode scalar values, but you want control over when or if you validate that assumption. -/// -/// # Examples -/// -/// ``` -/// use potential_utf::PotentialCodePoint; -/// -/// assert_eq!(PotentialCodePoint::from_u24(0x68).try_to_char(), Ok('h')); -/// assert_eq!(PotentialCodePoint::from_char('i').try_to_char(), Ok('i')); -/// assert_eq!( -/// PotentialCodePoint::from_u24(0x1F44B).try_to_char(), -/// Ok('👋') -/// ); -/// -/// assert!(PotentialCodePoint::from_u24(0xDE01).try_to_char().is_err()); -/// assert_eq!( -/// PotentialCodePoint::from_u24(0xDE01).to_char_lossy(), -/// char::REPLACEMENT_CHARACTER -/// ); -/// ``` -#[repr(transparent)] -#[allow(clippy::exhaustive_structs)] // transparent newtype -#[derive(PartialEq, Eq, Clone, Copy, Hash)] -pub struct PotentialCodePoint([u8; 3]); - -impl PotentialCodePoint { - /// Create a [`PotentialCodePoint`] from a `char`. - /// - /// # Examples - /// - /// ``` - /// use potential_utf::PotentialCodePoint; - /// - /// let a = PotentialCodePoint::from_char('a'); - /// assert_eq!(a.try_to_char().unwrap(), 'a'); - /// ``` - #[inline] - pub const fn from_char(c: char) -> Self { - let [u0, u1, u2, _u3] = (c as u32).to_le_bytes(); - Self([u0, u1, u2]) - } - - /// Create [`PotentialCodePoint`] from a u32 value, ignoring the most significant 8 bits. - #[inline] - pub const fn from_u24(c: u32) -> Self { - let [u0, u1, u2, _u3] = c.to_le_bytes(); - Self([u0, u1, u2]) - } - - /// Attempt to convert a [`PotentialCodePoint`] to a `char`. - /// - /// # Examples - /// - /// ``` - /// use potential_utf::PotentialCodePoint; - /// use zerovec::ule::AsULE; - /// - /// let a = PotentialCodePoint::from_char('a'); - /// assert_eq!(a.try_to_char(), Ok('a')); - /// - /// let b = PotentialCodePoint::from_unaligned([0xFF, 0xFF, 0xFF].into()); - /// assert!(matches!(b.try_to_char(), Err(_))); - /// ``` - #[inline] - pub fn try_to_char(self) -> Result<char, core::char::CharTryFromError> { - char::try_from(u32::from(self)) - } - - /// Convert a [`PotentialCodePoint`] to a `char', returning [`char::REPLACEMENT_CHARACTER`] - /// if the `PotentialCodePoint` does not represent a valid Unicode scalar value. - /// - /// # Examples - /// - /// ``` - /// use potential_utf::PotentialCodePoint; - /// use zerovec::ule::AsULE; - /// - /// let a = PotentialCodePoint::from_unaligned([0xFF, 0xFF, 0xFF].into()); - /// assert_eq!(a.to_char_lossy(), char::REPLACEMENT_CHARACTER); - /// ``` - #[inline] - pub fn to_char_lossy(self) -> char { - self.try_to_char().unwrap_or(char::REPLACEMENT_CHARACTER) - } - - /// Convert a [`PotentialCodePoint`] to a `char` without checking that it is - /// a valid Unicode scalar value. - /// - /// # Safety - /// - /// The `PotentialCodePoint` must be a valid Unicode scalar value in little-endian order. - /// - /// # Examples - /// - /// ``` - /// use potential_utf::PotentialCodePoint; - /// - /// let a = PotentialCodePoint::from_char('a'); - /// assert_eq!(unsafe { a.to_char_unchecked() }, 'a'); - /// ``` - #[inline] - pub unsafe fn to_char_unchecked(self) -> char { - char::from_u32_unchecked(u32::from(self)) - } - - /// For converting to the ULE type in a const context - /// - /// Can be removed once const traits are a thing - #[inline] - #[cfg(feature = "zerovec")] - pub const fn to_unaligned(self) -> zerovec::ule::RawBytesULE<3> { - zerovec::ule::RawBytesULE(self.0) - } -} - -/// This impl requires enabling the optional `zerovec` Cargo feature -#[cfg(feature = "zerovec")] -impl zerovec::ule::AsULE for PotentialCodePoint { - type ULE = zerovec::ule::RawBytesULE<3>; - - #[inline] - fn to_unaligned(self) -> Self::ULE { - zerovec::ule::RawBytesULE(self.0) - } - - #[inline] - fn from_unaligned(unaligned: Self::ULE) -> Self { - Self(unaligned.0) - } -} - -// Safety: PotentialCodePoint is always the little-endian representation of a char, -// which corresponds to its AsULE::ULE type -/// This impl requires enabling the optional `zerovec` Cargo feature -#[cfg(feature = "zerovec")] -unsafe impl zerovec::ule::EqULE for PotentialCodePoint {} - -impl fmt::Debug for PotentialCodePoint { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // Debug as a char if possible - match self.try_to_char() { - Ok(c) => fmt::Debug::fmt(&c, f), - Err(_) => fmt::Debug::fmt(&self.0, f), - } - } -} - -impl PartialOrd for PotentialCodePoint { - fn partial_cmp(&self, other: &Self) -> Option<Ordering> { - Some(self.cmp(other)) - } -} - -impl PartialEq<char> for PotentialCodePoint { - fn eq(&self, other: &char) -> bool { - self.eq(&Self::from_char(*other)) - } -} - -impl PartialOrd<char> for PotentialCodePoint { - fn partial_cmp(&self, other: &char) -> Option<Ordering> { - self.partial_cmp(&Self::from_char(*other)) - } -} - -impl PartialEq<PotentialCodePoint> for char { - fn eq(&self, other: &PotentialCodePoint) -> bool { - PotentialCodePoint::from_char(*self).eq(other) - } -} - -impl PartialOrd<PotentialCodePoint> for char { - fn partial_cmp(&self, other: &PotentialCodePoint) -> Option<Ordering> { - PotentialCodePoint::from_char(*self).partial_cmp(other) - } -} - -impl Ord for PotentialCodePoint { - // custom implementation, as derived Ord would compare lexicographically - fn cmp(&self, other: &Self) -> Ordering { - let a = u32::from(*self); - let b = u32::from(*other); - a.cmp(&b) - } -} - -impl From<PotentialCodePoint> for u32 { - fn from(x: PotentialCodePoint) -> Self { - let [a0, a1, a2] = x.0; - u32::from_le_bytes([a0, a1, a2, 0]) - } -} - -impl TryFrom<u32> for PotentialCodePoint { - type Error = (); - fn try_from(x: u32) -> Result<Self, ()> { - let [u0, u1, u2, u3] = x.to_le_bytes(); - if u3 != 0 { - return Err(()); - } - Ok(Self([u0, u1, u2])) - } -} - -impl From<char> for PotentialCodePoint { - #[inline] - fn from(value: char) -> Self { - Self::from_char(value) - } -} - -impl TryFrom<PotentialCodePoint> for char { - type Error = core::char::CharTryFromError; - - #[inline] - fn try_from(value: PotentialCodePoint) -> Result<char, Self::Error> { - value.try_to_char() - } -} - -/// This impl requires enabling the optional `serde` Cargo feature -#[cfg(feature = "serde")] -impl serde::Serialize for PotentialCodePoint { - fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> - where - S: serde::Serializer, - { - use serde::ser::Error; - let c = self - .try_to_char() - .map_err(|_| S::Error::custom("invalid Unicode scalar value in PotentialCodePoint"))?; - if serializer.is_human_readable() { - serializer.serialize_char(c) - } else { - self.0.serialize(serializer) - } - } -} - -/// This impl requires enabling the optional `serde` Cargo feature -#[cfg(feature = "serde")] -impl<'de> serde::Deserialize<'de> for PotentialCodePoint { - fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> - where - D: serde::Deserializer<'de>, - { - if deserializer.is_human_readable() { - let c = <char>::deserialize(deserializer)?; - Ok(PotentialCodePoint::from_char(c)) - } else { - let bytes = <[u8; 3]>::deserialize(deserializer)?; - Ok(PotentialCodePoint(bytes)) - } - } -} - -/// This impl requires enabling the optional `databake` Cargo feature -#[cfg(feature = "databake")] -impl databake::Bake for PotentialCodePoint { - fn bake(&self, env: &databake::CrateEnv) -> databake::TokenStream { - match self.try_to_char() { - Ok(ch) => { - env.insert("potential_utf"); - let ch = ch.bake(env); - databake::quote! { - potential_utf::PotentialCodePoint::from_char(#ch) - } - } - Err(_) => { - env.insert("potential_utf"); - let u24 = u32::from_le_bytes([self.0[0], self.0[1], self.0[2], 0]); - databake::quote! { - potential_utf::PotentialCodePoint::from_u24(#u24) - } - } - } - } -} - -#[cfg(test)] -mod test { - use super::*; - use zerovec::ZeroVec; - - #[test] - fn test_serde_fail() { - let uc = PotentialCodePoint([0xFF, 0xFF, 0xFF]); - serde_json::to_string(&uc).expect_err("serialize invalid char bytes"); - bincode::serialize(&uc).expect_err("serialize invalid char bytes"); - } - - #[test] - fn test_serde_json() { - let c = '🙃'; - let uc = PotentialCodePoint::from_char(c); - let json_ser = serde_json::to_string(&uc).unwrap(); - - assert_eq!(json_ser, r#""🙃""#); - - let json_de: PotentialCodePoint = serde_json::from_str(&json_ser).unwrap(); - - assert_eq!(uc, json_de); - } - - #[test] - fn test_serde_bincode() { - let c = '🙃'; - let uc = PotentialCodePoint::from_char(c); - let bytes_ser = bincode::serialize(&uc).unwrap(); - - assert_eq!(bytes_ser, [0x43, 0xF6, 0x01]); - - let bytes_de: PotentialCodePoint = bincode::deserialize(&bytes_ser).unwrap(); - - assert_eq!(uc, bytes_de); - } - - #[test] - fn test_representation() { - let chars = ['w', 'ω', '文', '𑄃', '🙃']; - - // backed by [PotentialCodePoint] - let uvchars: Vec<_> = chars - .iter() - .copied() - .map(PotentialCodePoint::from_char) - .collect(); - // backed by [RawBytesULE<3>] - let zvec: ZeroVec<_> = uvchars.clone().into_iter().collect(); - - let ule_bytes = zvec.as_bytes(); - let uvbytes; - unsafe { - let ptr = &uvchars[..] as *const _ as *const u8; - uvbytes = core::slice::from_raw_parts(ptr, ule_bytes.len()); - } - - // PotentialCodePoint is defined as little-endian, so this must be true on all platforms - // also asserts that to_unaligned/from_unaligned are no-ops - assert_eq!(uvbytes, ule_bytes); - - assert_eq!( - &[119, 0, 0, 201, 3, 0, 135, 101, 0, 3, 17, 1, 67, 246, 1], - ule_bytes - ); - } - - #[test] - fn test_char_bake() { - databake::test_bake!( - PotentialCodePoint, - const, - crate::PotentialCodePoint::from_char('b'), - potential_utf - ); - // surrogate code point - databake::test_bake!( - PotentialCodePoint, - const, - crate::PotentialCodePoint::from_u24(55296u32), - potential_utf - ); - } -} diff --git a/vendor/potential_utf/src/ustr.rs b/vendor/potential_utf/src/ustr.rs deleted file mode 100644 index 216f629b..00000000 --- a/vendor/potential_utf/src/ustr.rs +++ /dev/null @@ -1,270 +0,0 @@ -// 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 ). - -#[cfg(feature = "alloc")] -use alloc::boxed::Box; -use core::cmp::Ordering; -use core::fmt; -use core::ops::Deref; - -/// A byte slice that is expected to be a UTF-8 string but does not enforce that invariant. -/// -/// Use this type instead of `str` if you don't need to enforce UTF-8 during deserialization. For -/// example, strings that are keys of a map don't need to ever be reified as `str`s. -/// -/// [`PotentialUtf8`] derefs to `[u8]`. To obtain a `str`, use [`Self::try_as_str()`]. -/// -/// The main advantage of this type over `[u8]` is that it serializes as a string in -/// human-readable formats like JSON. -/// -/// # Examples -/// -/// Using an [`PotentialUtf8`] as the key of a [`ZeroMap`]: -/// -/// ``` -/// use potential_utf::PotentialUtf8; -/// use zerovec::ZeroMap; -/// -/// // This map is cheap to deserialize, as we don't need to perform UTF-8 validation. -/// let map: ZeroMap<PotentialUtf8, u8> = [ -/// (PotentialUtf8::from_bytes(b"abc"), 11), -/// (PotentialUtf8::from_bytes(b"def"), 22), -/// (PotentialUtf8::from_bytes(b"ghi"), 33), -/// ] -/// .into_iter() -/// .collect(); -/// -/// let key = "abc"; -/// let value = map.get_copied(PotentialUtf8::from_str(key)); -/// assert_eq!(Some(11), value); -/// ``` -/// -/// [`ZeroMap`]: zerovec::ZeroMap -#[repr(transparent)] -#[derive(PartialEq, Eq, PartialOrd, Ord)] -#[allow(clippy::exhaustive_structs)] // transparent newtype -pub struct PotentialUtf8(pub [u8]); - -impl fmt::Debug for PotentialUtf8 { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // Debug as a string if possible - match self.try_as_str() { - Ok(s) => fmt::Debug::fmt(s, f), - Err(_) => fmt::Debug::fmt(&self.0, f), - } - } -} - -impl PotentialUtf8 { - /// Create a [`PotentialUtf8`] from a byte slice. - #[inline] - pub const fn from_bytes(other: &[u8]) -> &Self { - // Safety: PotentialUtf8 is transparent over [u8] - unsafe { core::mem::transmute(other) } - } - - /// Create a [`PotentialUtf8`] from a string slice. - #[inline] - pub const fn from_str(s: &str) -> &Self { - Self::from_bytes(s.as_bytes()) - } - - /// Create a [`PotentialUtf8`] from boxed bytes. - #[inline] - #[cfg(feature = "alloc")] - pub fn from_boxed_bytes(other: Box<[u8]>) -> Box<Self> { - // Safety: PotentialUtf8 is transparent over [u8] - unsafe { core::mem::transmute(other) } - } - - /// Create a [`PotentialUtf8`] from a boxed `str`. - #[inline] - #[cfg(feature = "alloc")] - pub fn from_boxed_str(other: Box<str>) -> Box<Self> { - Self::from_boxed_bytes(other.into_boxed_bytes()) - } - - /// Get the bytes from a [`PotentialUtf8]. - #[inline] - pub const fn as_bytes(&self) -> &[u8] { - &self.0 - } - - /// Attempt to convert a [`PotentialUtf8`] to a `str`. - /// - /// # Examples - /// - /// ``` - /// use potential_utf::PotentialUtf8; - /// - /// static A: &PotentialUtf8 = PotentialUtf8::from_bytes(b"abc"); - /// - /// let b = A.try_as_str().unwrap(); - /// assert_eq!(b, "abc"); - /// ``` - // Note: this is const starting in 1.63 - #[inline] - pub fn try_as_str(&self) -> Result<&str, core::str::Utf8Error> { - core::str::from_utf8(&self.0) - } -} - -impl<'a> From<&'a str> for &'a PotentialUtf8 { - #[inline] - fn from(other: &'a str) -> Self { - PotentialUtf8::from_str(other) - } -} - -impl PartialEq<str> for PotentialUtf8 { - fn eq(&self, other: &str) -> bool { - self.eq(Self::from_str(other)) - } -} - -impl PartialOrd<str> for PotentialUtf8 { - fn partial_cmp(&self, other: &str) -> Option<Ordering> { - self.partial_cmp(Self::from_str(other)) - } -} - -impl PartialEq<PotentialUtf8> for str { - fn eq(&self, other: &PotentialUtf8) -> bool { - PotentialUtf8::from_str(self).eq(other) - } -} - -impl PartialOrd<PotentialUtf8> for str { - fn partial_cmp(&self, other: &PotentialUtf8) -> Option<Ordering> { - PotentialUtf8::from_str(self).partial_cmp(other) - } -} - -#[cfg(feature = "alloc")] -impl From<Box<str>> for Box<PotentialUtf8> { - #[inline] - fn from(other: Box<str>) -> Self { - PotentialUtf8::from_boxed_str(other) - } -} - -impl Deref for PotentialUtf8 { - type Target = [u8]; - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -/// This impl requires enabling the optional `zerovec` Cargo feature -#[cfg(all(feature = "zerovec", feature = "alloc"))] -impl<'a> zerovec::maps::ZeroMapKV<'a> for PotentialUtf8 { - type Container = zerovec::VarZeroVec<'a, PotentialUtf8>; - type Slice = zerovec::VarZeroSlice<PotentialUtf8>; - type GetType = PotentialUtf8; - type OwnedType = Box<PotentialUtf8>; -} - -// Safety (based on the safety checklist on the VarULE trait): -// 1. PotentialUtf8 does not include any uninitialized or padding bytes (transparent over a ULE) -// 2. PotentialUtf8 is aligned to 1 byte (transparent over a ULE) -// 3. The impl of `validate_bytes()` returns an error if any byte is not valid (impossible) -// 4. The impl of `validate_bytes()` returns an error if the slice cannot be used in its entirety (impossible) -// 5. The impl of `from_bytes_unchecked()` returns a reference to the same data (returns the argument directly) -// 6. All other methods are defaulted -// 7. `[T]` byte equality is semantic equality (transparent over a ULE) -/// This impl requires enabling the optional `zerovec` Cargo feature -#[cfg(feature = "zerovec")] -unsafe impl zerovec::ule::VarULE for PotentialUtf8 { - #[inline] - fn validate_bytes(_: &[u8]) -> Result<(), zerovec::ule::UleError> { - Ok(()) - } - #[inline] - unsafe fn from_bytes_unchecked(bytes: &[u8]) -> &Self { - PotentialUtf8::from_bytes(bytes) - } -} - -/// This impl requires enabling the optional `serde` Cargo feature -#[cfg(feature = "serde")] -impl serde::Serialize for PotentialUtf8 { - fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> - where - S: serde::Serializer, - { - use serde::ser::Error; - let s = self - .try_as_str() - .map_err(|_| S::Error::custom("invalid UTF-8 in PotentialUtf8"))?; - if serializer.is_human_readable() { - serializer.serialize_str(s) - } else { - serializer.serialize_bytes(s.as_bytes()) - } - } -} - -/// This impl requires enabling the optional `serde` Cargo feature -#[cfg(all(feature = "serde", feature = "alloc"))] -impl<'de> serde::Deserialize<'de> for Box<PotentialUtf8> { - fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> - where - D: serde::Deserializer<'de>, - { - if deserializer.is_human_readable() { - let boxed_str = Box::<str>::deserialize(deserializer)?; - Ok(PotentialUtf8::from_boxed_str(boxed_str)) - } else { - let boxed_bytes = Box::<[u8]>::deserialize(deserializer)?; - Ok(PotentialUtf8::from_boxed_bytes(boxed_bytes)) - } - } -} - -/// This impl requires enabling the optional `serde` Cargo feature -#[cfg(feature = "serde")] -impl<'de, 'a> serde::Deserialize<'de> for &'a PotentialUtf8 -where - 'de: 'a, -{ - fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> - where - D: serde::Deserializer<'de>, - { - if deserializer.is_human_readable() { - let s = <&str>::deserialize(deserializer)?; - Ok(PotentialUtf8::from_str(s)) - } else { - let bytes = <&[u8]>::deserialize(deserializer)?; - Ok(PotentialUtf8::from_bytes(bytes)) - } - } -} - -#[repr(transparent)] -#[derive(PartialEq, Eq, PartialOrd, Ord)] -#[allow(clippy::exhaustive_structs)] // transparent newtype -pub struct PotentialUtf16(pub [u16]); - -impl fmt::Debug for PotentialUtf16 { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // Debug as a string if possible - for c in char::decode_utf16(self.0.iter().copied()) { - match c { - Ok(c) => write!(f, "{c}")?, - Err(e) => write!(f, "\\0x{:x}", e.unpaired_surrogate())?, - } - } - Ok(()) - } -} - -impl PotentialUtf16 { - /// Create a [`PotentialUtf16`] from a u16 slice. - #[inline] - pub const fn from_slice(other: &[u16]) -> &Self { - // Safety: PotentialUtf16 is transparent over [u16] - unsafe { core::mem::transmute(other) } - } -} diff --git a/vendor/potential_utf/src/writeable.rs b/vendor/potential_utf/src/writeable.rs deleted file mode 100644 index cd489914..00000000 --- a/vendor/potential_utf/src/writeable.rs +++ /dev/null @@ -1,159 +0,0 @@ -// 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::{PotentialUtf16, PotentialUtf8}; -use alloc::borrow::Cow; -use core::fmt::Write; -use writeable::{LengthHint, Part, PartsWrite, TryWriteable}; - -use core::{char::DecodeUtf16Error, fmt, str::Utf8Error}; - -/// This impl requires enabling the optional `writeable` Cargo feature -impl TryWriteable for &'_ PotentialUtf8 { - type Error = Utf8Error; - - fn try_write_to_parts<S: PartsWrite + ?Sized>( - &self, - sink: &mut S, - ) -> Result<Result<(), Self::Error>, fmt::Error> { - let mut remaining = &self.0; - let mut r = Ok(()); - loop { - match core::str::from_utf8(remaining) { - Ok(valid) => { - sink.write_str(valid)?; - return Ok(r); - } - Err(e) => { - // SAFETY: By Utf8Error invariants - let valid = unsafe { - core::str::from_utf8_unchecked(remaining.get_unchecked(..e.valid_up_to())) - }; - sink.write_str(valid)?; - sink.with_part(Part::ERROR, |s| s.write_char(char::REPLACEMENT_CHARACTER))?; - if r.is_ok() { - r = Err(e); - } - let Some(error_len) = e.error_len() else { - return Ok(r); // end of string - }; - // SAFETY: By Utf8Error invariants - remaining = unsafe { remaining.get_unchecked(e.valid_up_to() + error_len..) } - } - } - } - } - - fn writeable_length_hint(&self) -> LengthHint { - // Lower bound is all valid UTF-8, upper bound is all bytes with the high bit, which become replacement characters. - LengthHint::between(self.0.len(), self.0.len() * 3) - } - - fn try_write_to_string(&self) -> Result<Cow<str>, (Self::Error, Cow<str>)> { - match core::str::from_utf8(&self.0) { - Ok(valid) => Ok(Cow::Borrowed(valid)), - Err(e) => { - // SAFETY: By Utf8Error invariants - let valid = unsafe { - core::str::from_utf8_unchecked(self.0.get_unchecked(..e.valid_up_to())) - }; - - // Let's assume this is the only error - let mut out = alloc::string::String::with_capacity( - self.0.len() + char::REPLACEMENT_CHARACTER.len_utf8() - - e.error_len().unwrap_or(0), - ); - - out.push_str(valid); - out.push(char::REPLACEMENT_CHARACTER); - - // If there's more, we can use `try_write_to` - if let Some(error_len) = e.error_len() { - // SAFETY: By Utf8Error invariants - let remaining = unsafe { self.0.get_unchecked(e.valid_up_to() + error_len..) }; - let _discard = PotentialUtf8::from_bytes(remaining).try_write_to(&mut out); - } - - Err((e, Cow::Owned(out))) - } - } - } -} - -/// This impl requires enabling the optional `writeable` Cargo feature -impl TryWriteable for &'_ PotentialUtf16 { - type Error = DecodeUtf16Error; - - fn try_write_to_parts<S: PartsWrite + ?Sized>( - &self, - sink: &mut S, - ) -> Result<Result<(), Self::Error>, fmt::Error> { - let mut r = Ok(()); - for c in core::char::decode_utf16(self.0.iter().copied()) { - match c { - Ok(c) => sink.write_char(c)?, - Err(e) => { - if r.is_ok() { - r = Err(e); - } - sink.with_part(Part::ERROR, |s| s.write_char(char::REPLACEMENT_CHARACTER))?; - } - } - } - Ok(r) - } - - fn writeable_length_hint(&self) -> LengthHint { - // Lower bound is all ASCII, upper bound is all 3-byte code points (including replacement character) - LengthHint::between(self.0.len(), self.0.len() * 3) - } -} - -#[cfg(test)] -mod test { - #![allow(invalid_from_utf8)] // only way to construct the error - use super::*; - use writeable::assert_try_writeable_parts_eq; - - #[test] - fn test_utf8() { - assert_try_writeable_parts_eq!( - PotentialUtf8::from_bytes(b"Foo Bar"), - "Foo Bar", - Ok(()), - [] - ); - assert_try_writeable_parts_eq!( - PotentialUtf8::from_bytes(b"Foo\xFDBar"), - "Foo�Bar", - Err(core::str::from_utf8(b"Foo\xFDBar").unwrap_err()), - [(3, 6, Part::ERROR)] - ); - assert_try_writeable_parts_eq!( - PotentialUtf8::from_bytes(b"Foo\xFDBar\xff"), - "Foo�Bar�", - Err(core::str::from_utf8(b"Foo\xFDBar\xff").unwrap_err()), - [(3, 6, Part::ERROR), (9, 12, Part::ERROR)], - ); - } - - #[test] - fn test_utf16() { - assert_try_writeable_parts_eq!( - PotentialUtf16::from_slice(&[0xD83E, 0xDD73]), - "🥳", - Ok(()), - [] - ); - assert_try_writeable_parts_eq!( - PotentialUtf16::from_slice(&[0xD83E, 0x20, 0xDD73]), - "� �", - Err(core::char::decode_utf16([0xD83E].into_iter()) - .next() - .unwrap() - .unwrap_err()), - [(0, 3, Part::ERROR), (4, 7, Part::ERROR)] - ); - } -} |
