pub struct Literal(/* private fields */);pipe only.Expand description
Zero allocation view of the literal text content of a JSON token.
To prevent allocation and minimize copying, a Literal may contain one or more Bytes
buffers that share memory with the Bytes values that were piped into the PipeAnalyzer.
Since these buffers have a uniform size, but JSON tokens can have arbitrary lengths, the text
content of a token may be split across two or more buffers. In other words, the full text of the
content may be non-contiguous in memory. To make this data structure usable in the widest range
of use cases, Literal implements the Buf trait, which provides a uniform interface for
reading data from potentially non-contiguous sources.
§Performance considerations
Clones are cheap and do not allocate. However, for the memory considerations described below, it is preferable to use short-lifetime clones for discrete tasks and not to proliferate long-lived clones.
§Memory considerations
Because a Literal may share memory with the Bytes buffers that were piped into a
PipeAnalyzer, holding on to a Literal instance may prevent the PipeAnalyzer from reusing
buffers. This can lead to increased memory usage. If all Literal instances produced by a
PipeAnalyzer are retained, they will tend to prevent any of the allocations backing the input
Bytes buffers from being dropped. This may undermine the value proposition of a streaming
analyzer and, for large enough JSON texts, may lead to out-of-memory conditions. Therefore, it
is advised that you retain Literal instances only as long as necessary to process them,
extracting owned copies of their data if you need long-lived access to the token text.
Implementations§
Source§impl Literal
impl Literal
Sourcepub const fn from_static(s: &'static str) -> Self
pub const fn from_static(s: &'static str) -> Self
Converts a static lifetime string slice to a literal value.
This function is the most efficient way to wrap a static string as a Literal. It does not
allocate and produces the lightest-weight Literal value.
If you have a non-static string slice, use from_ref, one of the From trait
implementations, or the FromStr implementation. If creating a literal value from an
owned String, use from_string.
§Examples
Populate and use a hash set of allowed JSON object keys.
use bufjson::lexical::{Token, pipe::{Literal, PipeAnalyzer}};
use bytes::Bytes;
use std::{collections::HashSet, sync::mpsc::channel, thread};
// Populate the set of allowed JSON object keys.
let mut allowed = HashSet::with_capacity(3);
allowed.insert(Literal::from_static(r#""foo""#)); // Note: store `"foo"`, not `foo`
allowed.insert(Literal::from_static(r#""baz""#)); // Note: store `"baz"`, not `baz`
// Parse some JSON.
let (tx, rx) = channel();
tx.send(r#"{"foo":"bar","baz":"qux"}"#.into()).unwrap();
drop(tx);
let mut parser = PipeAnalyzer::new(rx).into_parser();
// Verify that the literal value of every object key is allowed.
assert_eq!(Token::ObjBegin, parser.next());
loop {
match parser.next_meaningful() {
Token::Str => {
let key = parser.content().literal();
assert!(allowed.contains(&key));
assert_eq!(Token::Str, parser.next_meaningful()); // Skip corresponding value.
},
Token::ObjEnd => (),
Token::Eof => break,
_ => unreachable!(),
}
}Sourcepub fn from_ref<T: AsRef<str> + ?Sized>(s: &T) -> Self
pub fn from_ref<T: AsRef<str> + ?Sized>(s: &T) -> Self
Creates a literal value from anything that cheaply converts to a string slice reference.
If you have a static string slice, prefer from_static, which has a lower construction
cost and a more efficient implementation. If you have an owned String you can consume,
prefer from_string, which will avoid allocation. If you have a Cow you can consume,
prefer From<Cow<'_, str>>, which will avoid allocation if the Cow contains an owned
value.
Sourcepub fn from_string(s: String) -> Self
pub fn from_string(s: String) -> Self
Creates a literal value by consuming an owned string value.
§Examples
Create a literal from an owned string.
let s = "foo".to_string();
let lit = Literal::from_string(s);
assert_eq!("foo", lit);There is a From<String> implementation that is functionally equivalent.
let s = "bar".to_string();
let lit: Literal = s.into();
assert_eq!("bar", lit);Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the length of self.
This length is in bytes, not char values or graphemes. In other words, it might not be
what a human considers the length of the string.
§Examples
Get the length of a literal.
let boring = Literal::from_static("foo");
assert_eq!(3, boring.len());
let fancy = Literal::from_static("ƒoo"); // fancy f!
assert_eq!(fancy.len(), 4);Trait Implementations§
Source§impl Ord for Literal
impl Ord for Literal
Source§impl PartialOrd<&str> for Literal
impl PartialOrd<&str> for Literal
Source§impl PartialOrd<Literal> for &str
impl PartialOrd<Literal> for &str
Source§impl PartialOrd<Literal> for String
impl PartialOrd<Literal> for String
Source§impl PartialOrd<Literal> for str
impl PartialOrd<Literal> for str
Source§impl PartialOrd<String> for Literal
impl PartialOrd<String> for Literal
Source§impl PartialOrd<str> for Literal
impl PartialOrd<str> for Literal
Source§impl PartialOrd for Literal
impl PartialOrd for Literal
impl Eq for Literal
impl EqStr for Literal
Auto Trait Implementations§
impl Freeze for Literal
impl RefUnwindSafe for Literal
impl Send for Literal
impl Sync for Literal
impl Unpin for Literal
impl UnsafeUnpin for Literal
impl UnwindSafe for Literal
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.