cesu8_str/java/
mod.rs

1mod iter;
2mod str;
3
4#[cfg(feature = "alloc")]
5mod string;
6
7pub use iter::{JavaCharIndices, JavaChars};
8pub use str::JavaStr;
9
10#[cfg(feature = "alloc")]
11pub use string::JavaString;
12
13#[cfg(feature = "alloc")]
14use alloc::borrow::Cow;
15
16/// Computes the length of a character when encoded in the Java CESU-8 format.
17#[inline]
18#[must_use]
19pub const fn len_java(c: char) -> usize {
20    super::len_cesu8::<true>(c as u32)
21}
22
23/// Encodes a character as Java CESU-8 into the provided byte buffer, then
24/// returns the subslice of the buffer that contains the encoded character.
25#[inline]
26pub fn encode_java(c: char, dst: &mut [u8]) -> &mut [u8] {
27    super::encode_cesu8_raw::<true>(c as u32, dst)
28}
29
30/// Encodes a
31
32/// Converts a `JavaStr` into a `str`. We avoid copying unless necessary. In
33/// the case where there are no surrogate pairs, then no allocation will happen.
34///
35/// It is theoretically possible to convert a `JavaStr` into a UTF-8 string
36/// without allocation in any case, as the length of a Java CESU-8 string is
37/// always greater than or equal to the length of a UTF-8 string. This library
38/// does not currently provide this option.
39#[cfg(feature = "alloc")]
40#[inline]
41#[must_use]
42pub fn from_java_cesu8(str: &JavaStr) -> Cow<'_, str> {
43    super::from_cesu8::<true>(&str.internal)
44}
45
46/// Converts a `str` into a `JavaStr`. We avoid copying unless necessary. In
47/// the case where there are no four-byte encodings, then no allocation will
48/// happen.
49#[cfg(feature = "alloc")]
50#[inline]
51#[must_use]
52pub fn from_utf8(str: &str) -> Cow<'_, JavaStr> {
53    match super::from_utf8::<true>(str) {
54        Cow::Owned(string) => Cow::Owned(unsafe { JavaString::from_internal_unchecked(string) }),
55        Cow::Borrowed(str) => Cow::Borrowed(unsafe { JavaStr::from_internal_unchecked(str) }),
56    }
57}
58
59pub mod macros {
60    /// Builds a `JavaStr` literal at compile time from a string literal.
61    #[macro_export]
62    macro_rules! java_str {
63        ($str:tt) => {{
64            const _CESU8_STR_MACRO_STR: &str = $str;
65            const _CESU8_STR_MACRO_LEN: usize =
66                $crate::java::macros::required_java_len(_CESU8_STR_MACRO_STR);
67            const _CESU8_STR_MACRO_BUF: [u8; _CESU8_STR_MACRO_LEN] =
68                $crate::java::macros::create_java_array(_CESU8_STR_MACRO_STR);
69            unsafe { $crate::java::JavaStr::from_java_cesu8_unchecked(&_CESU8_STR_MACRO_BUF) }
70        }};
71    }
72
73    /// Calculate the amount of bytes required to encode `str` in Java CESU-8.
74    #[inline]
75    #[must_use]
76    pub const fn required_java_len(str: &str) -> usize {
77        crate::required_len::<false>(str)
78    }
79
80    /// Creates a buffer of Java CESU-8 encoded bytes from `str`.
81    #[inline]
82    #[must_use]
83    pub const fn create_java_array<const N: usize>(str: &str) -> [u8; N] {
84        crate::create_array::<false, N>(str)
85    }
86}
87
88#[cfg(test)]
89mod tests {
90    use crate::validate_cesu8_internal;
91
92    use super::encode_java;
93
94    #[test]
95    fn valid_roundtrip() {
96        let mut buf = [0; 6];
97        for i in 0..u32::MAX {
98            if let Some(c) = char::from_u32(i) {
99                let check = encode_java(c, &mut buf);
100                validate_cesu8_internal::<true>(check).unwrap();
101            }
102        }
103    }
104}