1#[cfg(feature = "alloc")]
2extern crate alloc;
3
4#[cfg(feature = "alloc")]
5use alloc::{borrow::ToOwned, string::String};
6
7use core::str::FromStr;
8
9use crate::{GString, Validator, error::GStringError};
10
11impl<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool> FromStr
13 for GString<V, MIN, MAX, ASCII_ONLY>
14{
15 type Err = GStringError<V::Err>;
16
17 fn from_str(s: &str) -> Result<Self, Self::Err> {
18 Self::try_new(s)
19 }
20}
21
22impl<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool> AsRef<str>
24 for GString<V, MIN, MAX, ASCII_ONLY>
25{
26 fn as_ref(&self) -> &str {
27 self.as_str()
28 }
29}
30
31#[cfg(feature = "alloc")]
33impl<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool> TryFrom<String>
34 for GString<V, MIN, MAX, ASCII_ONLY>
35{
36 type Error = GStringError<V::Err>;
37
38 fn try_from(value: String) -> Result<Self, Self::Error> {
39 Self::try_new(&value)
40 }
41}
42
43#[cfg(feature = "alloc")]
45impl<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool>
46 From<GString<V, MIN, MAX, ASCII_ONLY>> for String
47{
48 fn from(value: GString<V, MIN, MAX, ASCII_ONLY>) -> Self {
49 value.as_str().to_owned()
50 }
51}
52
53impl<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool> TryFrom<&str>
55 for GString<V, MIN, MAX, ASCII_ONLY>
56{
57 type Error = GStringError<V::Err>;
58
59 fn try_from(value: &str) -> Result<Self, Self::Error> {
60 Self::from_str(value)
61 }
62}
63
64impl<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool> AsRef<[u8]>
66 for GString<V, MIN, MAX, ASCII_ONLY>
67{
68 fn as_ref(&self) -> &[u8] {
69 self.as_bytes()
70 }
71}
72
73#[cfg(feature = "alloc")]
74impl<'a, V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool>
75 TryFrom<alloc::borrow::Cow<'a, str>> for GString<V, MIN, MAX, ASCII_ONLY>
76{
77 type Error = GStringError<V::Err>;
78
79 fn try_from(value: alloc::borrow::Cow<'a, str>) -> Result<Self, Self::Error> {
80 Self::from_str(&value)
81 }
82}
83
84impl<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool>
85 GString<V, MIN, MAX, ASCII_ONLY>
86{
87 pub fn try_from_iter<I, S>(iter: I) -> Result<Self, GStringError<V::Err>>
97 where
98 I: IntoIterator<Item = S>,
99 S: AsRef<str>,
100 {
101 let mut buf = [0u8; MAX];
102 let mut len = 0;
103
104 for s in iter {
105 let s = s.as_ref();
106 let bytes = s.as_bytes();
107
108 let end = len + bytes.len();
109
110 if end > MAX {
111 return Err(GStringError::TooLong(MAX));
112 }
113
114 buf[len..end].copy_from_slice(bytes);
115
116 len = end;
117 }
118
119 let candidate = unsafe { core::str::from_utf8_unchecked(&buf[..len]) };
122
123 Self::try_new(candidate)
124 }
125
126 pub fn try_from_chars<I>(iter: I) -> Result<Self, GStringError<V::Err>>
136 where
137 I: IntoIterator<Item = char>,
138 {
139 let mut buf = [0u8; MAX];
140 let mut len = 0;
141
142 for ch in iter {
143 let mut tmp = [0u8; 4];
144 let encoded = ch.encode_utf8(&mut tmp);
145
146 let bytes = encoded.as_bytes();
147 let end = len + bytes.len();
148
149 if end > MAX {
150 return Err(GStringError::TooLong(MAX));
151 }
152
153 buf[len..end].copy_from_slice(bytes);
154
155 len = end;
156 }
157
158 let candidate = unsafe { core::str::from_utf8_unchecked(&buf[..len]) };
161
162 Self::try_new(candidate)
163 }
164}