pub struct EString<E: Encoder> { /* private fields */ }alloc only.Expand description
A percent-encoded, growable string.
The borrowed counterpart of EString is EStr.
See its documentation for the meaning of the type parameter E.
§Comparison
EStrings are compared lexicographically
by their byte values. Normalization is not performed prior to comparison.
§Examples
Encode key-value pairs to a query string and use it to build a URI reference:
use fluent_uri::{
pct_enc::{
encoder::{Data, Query},
EStr, EString, Encoder, Table,
},
UriRef,
};
let pairs = [("name", "张三"), ("speech", "¡Olé!")];
let mut buf = EString::<Query>::new();
for (k, v) in pairs {
if !buf.is_empty() {
buf.push('&');
}
// WARNING: Absolutely do not confuse data with delimiters!
// Use `Data` (or `IData`) to encode data contained in a URI
// (or an IRI) unless you know what you're doing!
buf.encode_str::<Data>(k);
buf.push('=');
buf.encode_str::<Data>(v);
}
assert_eq!(buf, "name=%E5%BC%A0%E4%B8%89&speech=%C2%A1Ol%C3%A9%21");
let uri_ref = UriRef::builder()
.path(EStr::EMPTY)
.query(&buf)
.build()
.unwrap();
assert_eq!(uri_ref.as_str(), "?name=%E5%BC%A0%E4%B8%89&speech=%C2%A1Ol%C3%A9%21");Encode a path whose segments may contain the slash ('/') character
by using a custom sub-encoder:
use fluent_uri::pct_enc::{encoder::Path, EString, Encoder, Table};
struct PathSegment;
impl Encoder for PathSegment {
const TABLE: &'static Table = &Path::TABLE.sub(&Table::new(b"/"));
}
let mut path = EString::<Path>::new();
path.push('/');
path.encode_str::<PathSegment>("foo/bar");
assert_eq!(path, "/foo%2Fbar");Implementations§
Source§impl<E: Encoder> EString<E>
impl<E: Encoder> EString<E>
Sourcepub fn with_capacity(capacity: usize) -> Self
pub fn with_capacity(capacity: usize) -> Self
Creates a new empty EString with at least the specified capacity.
Sourcepub fn encode_str<SubE: Encoder>(&mut self, s: &str)
pub fn encode_str<SubE: Encoder>(&mut self, s: &str)
Encodes a string with a sub-encoder and appends the result onto the end of this EString.
A character will be preserved if SubE::TABLE allows it and percent-encoded otherwise.
In most cases, use Data (for URI) or IData (for IRI) as the sub-encoder.
When using other sub-encoders, make sure that SubE::TABLE does not allow
the component delimiters that delimit the data.
Note that this method will not encode U+0020 (space) as U+002B (+).
§Panics
Panics at compile time if SubE is not a sub-encoder of E,
or if SubE::TABLE does not allow percent-encoded octets.
Sourcepub fn encode_bytes<SubE: Encoder>(&mut self, bytes: &[u8])
👎Deprecated: use <[u8]>::utf8_chunks, EString::encode_str, EStr::encode_byte, and EString::push_estr instead
pub fn encode_bytes<SubE: Encoder>(&mut self, bytes: &[u8])
<[u8]>::utf8_chunks, EString::encode_str, EStr::encode_byte, and EString::push_estr insteadEncodes a byte sequence with a sub-encoder and appends the result onto the end of this EString.
A byte will be preserved if it is part of a UTF-8-encoded character
that SubE::TABLE allows and percent-encoded otherwise.
In most cases, use Data (for URI) or IData (for IRI) as the sub-encoder.
When using other sub-encoders, make sure that SubE::TABLE does not allow
the component delimiters that delimit the data.
Note that this method will not encode 0x20 (space) as U+002B (+).
If you need to encode a string, use encode_str instead.
§Deprecation
This method is deprecated because percent-encoding non-UTF-8 bytes is a non-standard operation. If you’re developing a new protocol, use other encodings such as Base64 instead. If you absolutely must, here’s a workaround:
use fluent_uri::pct_enc::{encoder::Path, EStr, EString};
let mut buf = EString::<Path>::new();
for chunk in b"D\xFCrst".utf8_chunks() {
buf.encode_str::<Path>(chunk.valid());
for &x in chunk.invalid() {
buf.push_estr(EStr::encode_byte(x));
}
}
assert_eq!(buf, "D%FCrst");§Panics
Panics at compile time if SubE is not a sub-encoder of E,
or if SubE::TABLE does not allow percent-encoded octets.
Sourcepub fn into_string(self) -> String
pub fn into_string(self) -> String
Consumes this EString and yields the underlying String.
Methods from Deref<Target = EStr<E>>§
pub const EMPTY: &'static Self
Sourcepub fn decode(&self) -> Decode<'_> ⓘ
pub fn decode(&self) -> Decode<'_> ⓘ
Returns an iterator used to decode the EStr slice.
Always split before decoding, as otherwise the data may be mistaken for component delimiters.
Note that the iterator will not decode U+002B (+) as 0x20 (space).
§Panics
Panics at compile time if E::TABLE does not allow percent-encoded octets.
§Examples
use fluent_uri::pct_enc::{encoder::Path, EStr};
let dec = EStr::<Path>::new_or_panic("%C2%A1Hola%21").decode();
assert_eq!(*dec.clone().to_bytes(), [0xc2, 0xa1, 0x48, 0x6f, 0x6c, 0x61, 0x21]);
assert_eq!(dec.to_string().unwrap(), "¡Hola!");Sourcepub fn split(&self, delim: char) -> Split<'_, E> ⓘ
pub fn split(&self, delim: char) -> Split<'_, E> ⓘ
Returns an iterator over subslices of the EStr slice separated by the given delimiter.
§Panics
Panics if the delimiter is not a reserved character.
§Examples
use fluent_uri::pct_enc::{encoder::Path, EStr};
assert!(EStr::<Path>::new_or_panic("a,b,c").split(',').eq(["a", "b", "c"]));
assert!(EStr::<Path>::new_or_panic(",").split(',').eq(["", ""]));
assert!(EStr::<Path>::EMPTY.split(',').eq([""]));Sourcepub fn split_once(&self, delim: char) -> Option<(&Self, &Self)>
pub fn split_once(&self, delim: char) -> Option<(&Self, &Self)>
Splits the EStr slice on the first occurrence of the given delimiter and
returns prefix before delimiter and suffix after delimiter.
Returns None if the delimiter is not found.
§Panics
Panics if the delimiter is not a reserved character.
§Examples
use fluent_uri::pct_enc::{encoder::Path, EStr};
assert_eq!(
EStr::<Path>::new_or_panic("foo;bar;baz").split_once(';'),
Some((EStr::new_or_panic("foo"), EStr::new_or_panic("bar;baz")))
);
assert_eq!(EStr::<Path>::new_or_panic("foo").split_once(';'), None);Sourcepub fn rsplit_once(&self, delim: char) -> Option<(&Self, &Self)>
pub fn rsplit_once(&self, delim: char) -> Option<(&Self, &Self)>
Splits the EStr slice on the last occurrence of the given delimiter and
returns prefix before delimiter and suffix after delimiter.
Returns None if the delimiter is not found.
§Panics
Panics if the delimiter is not a reserved character.
§Examples
use fluent_uri::pct_enc::{encoder::Path, EStr};
assert_eq!(
EStr::<Path>::new_or_panic("foo;bar;baz").rsplit_once(';'),
Some((EStr::new_or_panic("foo;bar"), EStr::new_or_panic("baz")))
);
assert_eq!(EStr::<Path>::new_or_panic("foo").rsplit_once(';'), None);Sourcepub fn is_absolute(&self) -> bool
pub fn is_absolute(&self) -> bool
Checks whether the path is absolute, i.e., starting with '/'.
Sourcepub fn is_rootless(&self) -> bool
pub fn is_rootless(&self) -> bool
Checks whether the path is rootless, i.e., not starting with '/'.
Sourcepub fn segments_if_absolute(&self) -> Option<Split<'_, E>>
pub fn segments_if_absolute(&self) -> Option<Split<'_, E>>
Returns an iterator over the path segments, separated by '/'.
Returns None if the path is rootless. Use split
instead if you need to split a rootless path on occurrences of '/'.
Note that the path can be empty when authority is present,
in which case this method will return None.
§Examples
use fluent_uri::Uri;
// Segments are separated by '/'.
// The empty string before a leading '/' is not a segment.
// However, segments can be empty in the other cases.
let path = Uri::parse("file:///path/to//dir/")?.path();
assert_eq!(path, "/path/to//dir/");
assert!(path.segments_if_absolute().unwrap().eq(["path", "to", "", "dir", ""]));
let path = Uri::parse("foo:bar/baz")?.path();
assert_eq!(path, "bar/baz");
assert!(path.segments_if_absolute().is_none());
let path = Uri::parse("http://example.com")?.path();
assert!(path.is_empty());
assert!(path.segments_if_absolute().is_none());