From 28a1e3a3f0213d67a6e6c9f1f405c006cc088e4d Mon Sep 17 00:00:00 2001 From: Michael Pfaff Date: Fri, 15 Mar 2024 19:44:55 -0400 Subject: [PATCH] Export some escaping utilities, refactor a little bit --- sailfish/src/escape.rs | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/sailfish/src/escape.rs b/sailfish/src/escape.rs index 83ffff0..8bed03d 100644 --- a/sailfish/src/escape.rs +++ b/sailfish/src/escape.rs @@ -4,8 +4,22 @@ use array_vec::ArrayStr; use super::Buffer; -pub(crate) struct CommonIdents(PhantomData); +/// Holds computed constants for common escaping scheme identity checks. +pub struct CommonIdents(PhantomData); +/// Converts an array of ASCII bytes to an array of characters. +pub const fn ascii_chars(s: &[u8; N]) -> [char; N] { + assert!(s.is_ascii()); + let mut chars = ['\0'; N]; + let mut i = 0; + while i < s.len() { + chars[i] = s[i] as char; + i += 1; + } + chars +} + +/// Returns `true` if, for the given escaping scheme `E`, every character in `set` requires no escaping. pub const fn are_all_chars_identity(set: &[char]) -> bool { let mut i = 0; while i < set.len() { @@ -17,19 +31,21 @@ pub const fn are_all_chars_identity(set: &[char]) true } +const BOOL_CHARS: &[char] = &ascii_chars(b"truefals"); +const UINT_CHARS: &[char] = &ascii_chars(b"0123456789"); + impl CommonIdents { /// True if `true` and `false` will never need escaping. - pub const BOOLS: bool = - are_all_chars_identity::(&['t', 'r', 'u', 'e', 'f', 'a', 'l', 's']); + pub const BOOLS: bool = are_all_chars_identity::(BOOL_CHARS); /// True if unsigned integers will never need escaping. - pub const UINTS: bool = - are_all_chars_identity::(&['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']); + pub const UINTS: bool = are_all_chars_identity::(UINT_CHARS); /// True if signed integers will never need escaping. pub const INTS: bool = Self::UINTS && are_all_chars_identity::(&['-']); /// True if floats (using [`ryu`]'s formatting) will never need escaping. pub const FLOATS: bool = Self::INTS && are_all_chars_identity::(&['.', 'e']); } +/// Constant metadata about an impl of [`Escape`]. #[const_trait] pub trait EscapeMeta { /// Returns `true` if the escaping scheme will never map the given character, regardless of its