chore: checkpoint before Python removal

This commit is contained in:
2026-03-26 22:33:59 +00:00
parent 683cec9307
commit e568ddf82a
29972 changed files with 11269302 additions and 2 deletions

1846
vendor/serde_yaml/src/de.rs vendored Normal file

File diff suppressed because it is too large Load Diff

290
vendor/serde_yaml/src/error.rs vendored Normal file
View File

@@ -0,0 +1,290 @@
use crate::libyaml::{emitter, error as libyaml};
use crate::path::Path;
use serde::{de, ser};
use std::error::Error as StdError;
use std::fmt::{self, Debug, Display};
use std::io;
use std::result;
use std::string;
use std::sync::Arc;
/// An error that happened serializing or deserializing YAML data.
pub struct Error(Box<ErrorImpl>);
/// Alias for a `Result` with the error type `serde_yaml::Error`.
pub type Result<T> = result::Result<T, Error>;
#[derive(Debug)]
pub(crate) enum ErrorImpl {
Message(String, Option<Pos>),
Libyaml(libyaml::Error),
Io(io::Error),
FromUtf8(string::FromUtf8Error),
EndOfStream,
MoreThanOneDocument,
RecursionLimitExceeded(libyaml::Mark),
RepetitionLimitExceeded,
BytesUnsupported,
UnknownAnchor(libyaml::Mark),
SerializeNestedEnum,
ScalarInMerge,
TaggedInMerge,
ScalarInMergeElement,
SequenceInMergeElement,
EmptyTag,
FailedToParseNumber,
Shared(Arc<ErrorImpl>),
}
#[derive(Debug)]
pub(crate) struct Pos {
mark: libyaml::Mark,
path: String,
}
/// The input location that an error occured.
#[derive(Debug)]
pub struct Location {
index: usize,
line: usize,
column: usize,
}
impl Location {
/// The byte index of the error
pub fn index(&self) -> usize {
self.index
}
/// The line of the error
pub fn line(&self) -> usize {
self.line
}
/// The column of the error
pub fn column(&self) -> usize {
self.column
}
// This is to keep decoupled with the yaml crate
#[doc(hidden)]
fn from_mark(mark: libyaml::Mark) -> Self {
Location {
index: mark.index() as usize,
// `line` and `column` returned from libyaml are 0-indexed but all error messages add +1 to this value
line: mark.line() as usize + 1,
column: mark.column() as usize + 1,
}
}
}
impl Error {
/// Returns the Location from the error if one exists.
///
/// Not all types of errors have a location so this can return `None`.
///
/// # Examples
///
/// ```
/// # use serde_yaml::{Value, Error};
/// #
/// // The `@` character as the first character makes this invalid yaml
/// let invalid_yaml: Result<Value, Error> = serde_yaml::from_str("@invalid_yaml");
///
/// let location = invalid_yaml.unwrap_err().location().unwrap();
///
/// assert_eq!(location.line(), 1);
/// assert_eq!(location.column(), 1);
/// ```
pub fn location(&self) -> Option<Location> {
self.0.location()
}
}
pub(crate) fn new(inner: ErrorImpl) -> Error {
Error(Box::new(inner))
}
pub(crate) fn shared(shared: Arc<ErrorImpl>) -> Error {
Error(Box::new(ErrorImpl::Shared(shared)))
}
pub(crate) fn fix_mark(mut error: Error, mark: libyaml::Mark, path: Path) -> Error {
if let ErrorImpl::Message(_, none @ None) = error.0.as_mut() {
*none = Some(Pos {
mark,
path: path.to_string(),
});
}
error
}
impl Error {
pub(crate) fn shared(self) -> Arc<ErrorImpl> {
if let ErrorImpl::Shared(err) = *self.0 {
err
} else {
Arc::from(self.0)
}
}
}
impl From<libyaml::Error> for Error {
fn from(err: libyaml::Error) -> Self {
Error(Box::new(ErrorImpl::Libyaml(err)))
}
}
impl From<emitter::Error> for Error {
fn from(err: emitter::Error) -> Self {
match err {
emitter::Error::Libyaml(err) => Self::from(err),
emitter::Error::Io(err) => new(ErrorImpl::Io(err)),
}
}
}
impl StdError for Error {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
self.0.source()
}
}
impl Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.display(f)
}
}
// Remove two layers of verbosity from the debug representation. Humans often
// end up seeing this representation because it is what unwrap() shows.
impl Debug for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.debug(f)
}
}
impl ser::Error for Error {
fn custom<T: Display>(msg: T) -> Self {
Error(Box::new(ErrorImpl::Message(msg.to_string(), None)))
}
}
impl de::Error for Error {
fn custom<T: Display>(msg: T) -> Self {
Error(Box::new(ErrorImpl::Message(msg.to_string(), None)))
}
}
impl ErrorImpl {
fn location(&self) -> Option<Location> {
self.mark().map(Location::from_mark)
}
fn source(&self) -> Option<&(dyn StdError + 'static)> {
match self {
ErrorImpl::Io(err) => err.source(),
ErrorImpl::FromUtf8(err) => err.source(),
ErrorImpl::Shared(err) => err.source(),
_ => None,
}
}
fn mark(&self) -> Option<libyaml::Mark> {
match self {
ErrorImpl::Message(_, Some(Pos { mark, path: _ }))
| ErrorImpl::RecursionLimitExceeded(mark)
| ErrorImpl::UnknownAnchor(mark) => Some(*mark),
ErrorImpl::Libyaml(err) => Some(err.mark()),
ErrorImpl::Shared(err) => err.mark(),
_ => None,
}
}
fn message_no_mark(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ErrorImpl::Message(msg, None) => f.write_str(msg),
ErrorImpl::Message(msg, Some(Pos { mark: _, path })) => {
if path != "." {
write!(f, "{}: ", path)?;
}
f.write_str(msg)
}
ErrorImpl::Libyaml(_) => unreachable!(),
ErrorImpl::Io(err) => Display::fmt(err, f),
ErrorImpl::FromUtf8(err) => Display::fmt(err, f),
ErrorImpl::EndOfStream => f.write_str("EOF while parsing a value"),
ErrorImpl::MoreThanOneDocument => f.write_str(
"deserializing from YAML containing more than one document is not supported",
),
ErrorImpl::RecursionLimitExceeded(_mark) => f.write_str("recursion limit exceeded"),
ErrorImpl::RepetitionLimitExceeded => f.write_str("repetition limit exceeded"),
ErrorImpl::BytesUnsupported => {
f.write_str("serialization and deserialization of bytes in YAML is not implemented")
}
ErrorImpl::UnknownAnchor(_mark) => f.write_str("unknown anchor"),
ErrorImpl::SerializeNestedEnum => {
f.write_str("serializing nested enums in YAML is not supported yet")
}
ErrorImpl::ScalarInMerge => {
f.write_str("expected a mapping or list of mappings for merging, but found scalar")
}
ErrorImpl::TaggedInMerge => f.write_str("unexpected tagged value in merge"),
ErrorImpl::ScalarInMergeElement => {
f.write_str("expected a mapping for merging, but found scalar")
}
ErrorImpl::SequenceInMergeElement => {
f.write_str("expected a mapping for merging, but found sequence")
}
ErrorImpl::EmptyTag => f.write_str("empty YAML tag is not allowed"),
ErrorImpl::FailedToParseNumber => f.write_str("failed to parse YAML number"),
ErrorImpl::Shared(_) => unreachable!(),
}
}
fn display(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ErrorImpl::Libyaml(err) => Display::fmt(err, f),
ErrorImpl::Shared(err) => err.display(f),
_ => {
self.message_no_mark(f)?;
if let Some(mark) = self.mark() {
if mark.line() != 0 || mark.column() != 0 {
write!(f, " at {}", mark)?;
}
}
Ok(())
}
}
}
fn debug(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ErrorImpl::Libyaml(err) => Debug::fmt(err, f),
ErrorImpl::Shared(err) => err.debug(f),
_ => {
f.write_str("Error(")?;
struct MessageNoMark<'a>(&'a ErrorImpl);
impl<'a> Display for MessageNoMark<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.message_no_mark(f)
}
}
let msg = MessageNoMark(self).to_string();
Debug::fmt(&msg, f)?;
if let Some(mark) = self.mark() {
write!(
f,
", line: {}, column: {}",
mark.line() + 1,
mark.column() + 1,
)?;
}
f.write_str(")")
}
}
}
}

191
vendor/serde_yaml/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,191 @@
//! [![github]](https://github.com/dtolnay/serde-yaml)&ensp;[![crates-io]](https://crates.io/crates/serde-yaml)&ensp;[![docs-rs]](https://docs.rs/serde-yaml)
//!
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
//!
//! <br>
//!
//! Rust library for using the [Serde] serialization framework with data in
//! [YAML] file format. _(This project is no longer maintained.)_
//!
//! [Serde]: https://github.com/serde-rs/serde
//! [YAML]: https://yaml.org/
//!
//! # Examples
//!
//! ```
//! use std::collections::BTreeMap;
//!
//! fn main() -> Result<(), serde_yaml::Error> {
//! // You have some type.
//! let mut map = BTreeMap::new();
//! map.insert("x".to_string(), 1.0);
//! map.insert("y".to_string(), 2.0);
//!
//! // Serialize it to a YAML string.
//! let yaml = serde_yaml::to_string(&map)?;
//! assert_eq!(yaml, "x: 1.0\ny: 2.0\n");
//!
//! // Deserialize it back to a Rust type.
//! let deserialized_map: BTreeMap<String, f64> = serde_yaml::from_str(&yaml)?;
//! assert_eq!(map, deserialized_map);
//! Ok(())
//! }
//! ```
//!
//! ## Using Serde derive
//!
//! It can also be used with Serde's derive macros to handle structs and enums
//! defined in your program.
//!
//! Structs serialize in the obvious way:
//!
//! ```
//! # use serde_derive::{Serialize, Deserialize};
//! use serde::{Serialize, Deserialize};
//!
//! #[derive(Serialize, Deserialize, PartialEq, Debug)]
//! struct Point {
//! x: f64,
//! y: f64,
//! }
//!
//! fn main() -> Result<(), serde_yaml::Error> {
//! let point = Point { x: 1.0, y: 2.0 };
//!
//! let yaml = serde_yaml::to_string(&point)?;
//! assert_eq!(yaml, "x: 1.0\ny: 2.0\n");
//!
//! let deserialized_point: Point = serde_yaml::from_str(&yaml)?;
//! assert_eq!(point, deserialized_point);
//! Ok(())
//! }
//! ```
//!
//! Enums serialize using YAML's `!tag` syntax to identify the variant name.
//!
//! ```
//! # use serde_derive::{Serialize, Deserialize};
//! use serde::{Serialize, Deserialize};
//!
//! #[derive(Serialize, Deserialize, PartialEq, Debug)]
//! enum Enum {
//! Unit,
//! Newtype(usize),
//! Tuple(usize, usize, usize),
//! Struct { x: f64, y: f64 },
//! }
//!
//! fn main() -> Result<(), serde_yaml::Error> {
//! let yaml = "
//! - !Newtype 1
//! - !Tuple [0, 0, 0]
//! - !Struct {x: 1.0, y: 2.0}
//! ";
//! let values: Vec<Enum> = serde_yaml::from_str(yaml).unwrap();
//! assert_eq!(values[0], Enum::Newtype(1));
//! assert_eq!(values[1], Enum::Tuple(0, 0, 0));
//! assert_eq!(values[2], Enum::Struct { x: 1.0, y: 2.0 });
//!
//! // The last two in YAML's block style instead:
//! let yaml = "
//! - !Tuple
//! - 0
//! - 0
//! - 0
//! - !Struct
//! x: 1.0
//! y: 2.0
//! ";
//! let values: Vec<Enum> = serde_yaml::from_str(yaml).unwrap();
//! assert_eq!(values[0], Enum::Tuple(0, 0, 0));
//! assert_eq!(values[1], Enum::Struct { x: 1.0, y: 2.0 });
//!
//! // Variants with no data can be written using !Tag or just the string name.
//! let yaml = "
//! - Unit # serialization produces this one
//! - !Unit
//! ";
//! let values: Vec<Enum> = serde_yaml::from_str(yaml).unwrap();
//! assert_eq!(values[0], Enum::Unit);
//! assert_eq!(values[1], Enum::Unit);
//!
//! Ok(())
//! }
//! ```
#![doc(html_root_url = "https://docs.rs/serde_yaml/0.9.34+deprecated")]
#![deny(missing_docs, unsafe_op_in_unsafe_fn)]
// Suppressed clippy_pedantic lints
#![allow(
// buggy
clippy::iter_not_returning_iterator, // https://github.com/rust-lang/rust-clippy/issues/8285
clippy::ptr_arg, // https://github.com/rust-lang/rust-clippy/issues/9218
clippy::question_mark, // https://github.com/rust-lang/rust-clippy/issues/7859
// private Deserializer::next
clippy::should_implement_trait,
// things are often more readable this way
clippy::cast_lossless,
clippy::checked_conversions,
clippy::if_not_else,
clippy::manual_assert,
clippy::match_like_matches_macro,
clippy::match_same_arms,
clippy::module_name_repetitions,
clippy::needless_pass_by_value,
clippy::redundant_else,
clippy::single_match_else,
// code is acceptable
clippy::blocks_in_conditions,
clippy::cast_possible_truncation,
clippy::cast_possible_wrap,
clippy::cast_precision_loss,
clippy::cast_sign_loss,
clippy::derive_partial_eq_without_eq,
clippy::derived_hash_with_manual_eq,
clippy::doc_markdown,
clippy::items_after_statements,
clippy::let_underscore_untyped,
clippy::manual_map,
clippy::missing_panics_doc,
clippy::never_loop,
clippy::return_self_not_must_use,
clippy::too_many_lines,
clippy::uninlined_format_args,
clippy::unsafe_removed_from_name,
clippy::wildcard_in_or_patterns,
// noisy
clippy::missing_errors_doc,
clippy::must_use_candidate,
)]
pub use crate::de::{from_reader, from_slice, from_str, Deserializer};
pub use crate::error::{Error, Location, Result};
pub use crate::ser::{to_string, to_writer, Serializer};
#[doc(inline)]
pub use crate::value::{from_value, to_value, Index, Number, Sequence, Value};
#[doc(inline)]
pub use crate::mapping::Mapping;
mod de;
mod error;
mod libyaml;
mod loader;
pub mod mapping;
mod number;
mod path;
mod ser;
pub mod value;
pub mod with;
// Prevent downstream code from implementing the Index trait.
mod private {
pub trait Sealed {}
impl Sealed for usize {}
impl Sealed for str {}
impl Sealed for String {}
impl Sealed for crate::Value {}
impl<'a, T> Sealed for &'a T where T: ?Sized + Sealed {}
}

127
vendor/serde_yaml/src/libyaml/cstr.rs vendored Normal file
View File

@@ -0,0 +1,127 @@
use std::fmt::{self, Debug, Display, Write as _};
use std::marker::PhantomData;
use std::ptr::NonNull;
use std::slice;
use std::str;
#[derive(Copy, Clone)]
pub(crate) struct CStr<'a> {
ptr: NonNull<u8>,
marker: PhantomData<&'a [u8]>,
}
unsafe impl<'a> Send for CStr<'a> {}
unsafe impl<'a> Sync for CStr<'a> {}
impl<'a> CStr<'a> {
pub fn from_bytes_with_nul(bytes: &'static [u8]) -> Self {
assert_eq!(bytes.last(), Some(&b'\0'));
let ptr = NonNull::from(bytes).cast();
unsafe { Self::from_ptr(ptr) }
}
pub unsafe fn from_ptr(ptr: NonNull<i8>) -> Self {
CStr {
ptr: ptr.cast(),
marker: PhantomData,
}
}
pub fn len(self) -> usize {
let start = self.ptr.as_ptr();
let mut end = start;
unsafe {
while *end != 0 {
end = end.add(1);
}
end.offset_from(start) as usize
}
}
pub fn to_bytes(self) -> &'a [u8] {
let len = self.len();
unsafe { slice::from_raw_parts(self.ptr.as_ptr(), len) }
}
}
impl<'a> Display for CStr<'a> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let ptr = self.ptr.as_ptr();
let len = self.len();
let bytes = unsafe { slice::from_raw_parts(ptr, len) };
display_lossy(bytes, formatter)
}
}
impl<'a> Debug for CStr<'a> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let ptr = self.ptr.as_ptr();
let len = self.len();
let bytes = unsafe { slice::from_raw_parts(ptr, len) };
debug_lossy(bytes, formatter)
}
}
fn display_lossy(mut bytes: &[u8], formatter: &mut fmt::Formatter) -> fmt::Result {
loop {
match str::from_utf8(bytes) {
Ok(valid) => return formatter.write_str(valid),
Err(utf8_error) => {
let valid_up_to = utf8_error.valid_up_to();
let valid = unsafe { str::from_utf8_unchecked(&bytes[..valid_up_to]) };
formatter.write_str(valid)?;
formatter.write_char(char::REPLACEMENT_CHARACTER)?;
if let Some(error_len) = utf8_error.error_len() {
bytes = &bytes[valid_up_to + error_len..];
} else {
return Ok(());
}
}
}
}
}
pub(crate) fn debug_lossy(mut bytes: &[u8], formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_char('"')?;
while !bytes.is_empty() {
let from_utf8_result = str::from_utf8(bytes);
let valid = match from_utf8_result {
Ok(valid) => valid,
Err(utf8_error) => {
let valid_up_to = utf8_error.valid_up_to();
unsafe { str::from_utf8_unchecked(&bytes[..valid_up_to]) }
}
};
let mut written = 0;
for (i, ch) in valid.char_indices() {
let esc = ch.escape_debug();
if esc.len() != 1 && ch != '\'' {
formatter.write_str(&valid[written..i])?;
for ch in esc {
formatter.write_char(ch)?;
}
written = i + ch.len_utf8();
}
}
formatter.write_str(&valid[written..])?;
match from_utf8_result {
Ok(_valid) => break,
Err(utf8_error) => {
let end_of_broken = if let Some(error_len) = utf8_error.error_len() {
valid.len() + error_len
} else {
bytes.len()
};
for b in &bytes[valid.len()..end_of_broken] {
write!(formatter, "\\x{:02x}", b)?;
}
bytes = &bytes[end_of_broken..];
}
}
}
formatter.write_char('"')
}

217
vendor/serde_yaml/src/libyaml/emitter.rs vendored Normal file
View File

@@ -0,0 +1,217 @@
use crate::libyaml;
use crate::libyaml::util::Owned;
use std::ffi::c_void;
use std::io;
use std::mem::{self, MaybeUninit};
use std::ptr::{self, addr_of_mut};
use std::slice;
use unsafe_libyaml as sys;
#[derive(Debug)]
pub(crate) enum Error {
Libyaml(libyaml::error::Error),
Io(io::Error),
}
pub(crate) struct Emitter<'a> {
pin: Owned<EmitterPinned<'a>>,
}
struct EmitterPinned<'a> {
sys: sys::yaml_emitter_t,
write: Box<dyn io::Write + 'a>,
write_error: Option<io::Error>,
}
#[derive(Debug)]
pub(crate) enum Event<'a> {
StreamStart,
StreamEnd,
DocumentStart,
DocumentEnd,
Scalar(Scalar<'a>),
SequenceStart(Sequence),
SequenceEnd,
MappingStart(Mapping),
MappingEnd,
}
#[derive(Debug)]
pub(crate) struct Scalar<'a> {
pub tag: Option<String>,
pub value: &'a str,
pub style: ScalarStyle,
}
#[derive(Debug)]
pub(crate) enum ScalarStyle {
Any,
Plain,
SingleQuoted,
Literal,
}
#[derive(Debug)]
pub(crate) struct Sequence {
pub tag: Option<String>,
}
#[derive(Debug)]
pub(crate) struct Mapping {
pub tag: Option<String>,
}
impl<'a> Emitter<'a> {
pub fn new(write: Box<dyn io::Write + 'a>) -> Emitter<'a> {
let owned = Owned::<EmitterPinned>::new_uninit();
let pin = unsafe {
let emitter = addr_of_mut!((*owned.ptr).sys);
if sys::yaml_emitter_initialize(emitter).fail {
panic!("malloc error: {}", libyaml::Error::emit_error(emitter));
}
sys::yaml_emitter_set_unicode(emitter, true);
sys::yaml_emitter_set_width(emitter, -1);
addr_of_mut!((*owned.ptr).write).write(write);
addr_of_mut!((*owned.ptr).write_error).write(None);
sys::yaml_emitter_set_output(emitter, write_handler, owned.ptr.cast());
Owned::assume_init(owned)
};
Emitter { pin }
}
pub fn emit(&mut self, event: Event) -> Result<(), Error> {
let mut sys_event = MaybeUninit::<sys::yaml_event_t>::uninit();
let sys_event = sys_event.as_mut_ptr();
unsafe {
let emitter = addr_of_mut!((*self.pin.ptr).sys);
let initialize_status = match event {
Event::StreamStart => {
sys::yaml_stream_start_event_initialize(sys_event, sys::YAML_UTF8_ENCODING)
}
Event::StreamEnd => sys::yaml_stream_end_event_initialize(sys_event),
Event::DocumentStart => {
let version_directive = ptr::null_mut();
let tag_directives_start = ptr::null_mut();
let tag_directives_end = ptr::null_mut();
let implicit = true;
sys::yaml_document_start_event_initialize(
sys_event,
version_directive,
tag_directives_start,
tag_directives_end,
implicit,
)
}
Event::DocumentEnd => {
let implicit = true;
sys::yaml_document_end_event_initialize(sys_event, implicit)
}
Event::Scalar(mut scalar) => {
let anchor = ptr::null();
let tag = scalar.tag.as_mut().map_or_else(ptr::null, |tag| {
tag.push('\0');
tag.as_ptr()
});
let value = scalar.value.as_ptr();
let length = scalar.value.len() as i32;
let plain_implicit = tag.is_null();
let quoted_implicit = tag.is_null();
let style = match scalar.style {
ScalarStyle::Any => sys::YAML_ANY_SCALAR_STYLE,
ScalarStyle::Plain => sys::YAML_PLAIN_SCALAR_STYLE,
ScalarStyle::SingleQuoted => sys::YAML_SINGLE_QUOTED_SCALAR_STYLE,
ScalarStyle::Literal => sys::YAML_LITERAL_SCALAR_STYLE,
};
sys::yaml_scalar_event_initialize(
sys_event,
anchor,
tag,
value,
length,
plain_implicit,
quoted_implicit,
style,
)
}
Event::SequenceStart(mut sequence) => {
let anchor = ptr::null();
let tag = sequence.tag.as_mut().map_or_else(ptr::null, |tag| {
tag.push('\0');
tag.as_ptr()
});
let implicit = tag.is_null();
let style = sys::YAML_ANY_SEQUENCE_STYLE;
sys::yaml_sequence_start_event_initialize(
sys_event, anchor, tag, implicit, style,
)
}
Event::SequenceEnd => sys::yaml_sequence_end_event_initialize(sys_event),
Event::MappingStart(mut mapping) => {
let anchor = ptr::null();
let tag = mapping.tag.as_mut().map_or_else(ptr::null, |tag| {
tag.push('\0');
tag.as_ptr()
});
let implicit = tag.is_null();
let style = sys::YAML_ANY_MAPPING_STYLE;
sys::yaml_mapping_start_event_initialize(
sys_event, anchor, tag, implicit, style,
)
}
Event::MappingEnd => sys::yaml_mapping_end_event_initialize(sys_event),
};
if initialize_status.fail {
return Err(Error::Libyaml(libyaml::Error::emit_error(emitter)));
}
if sys::yaml_emitter_emit(emitter, sys_event).fail {
return Err(self.error());
}
}
Ok(())
}
pub fn flush(&mut self) -> Result<(), Error> {
unsafe {
let emitter = addr_of_mut!((*self.pin.ptr).sys);
if sys::yaml_emitter_flush(emitter).fail {
return Err(self.error());
}
}
Ok(())
}
pub fn into_inner(self) -> Box<dyn io::Write + 'a> {
let sink = Box::new(io::sink());
unsafe { mem::replace(&mut (*self.pin.ptr).write, sink) }
}
fn error(&mut self) -> Error {
let emitter = unsafe { &mut *self.pin.ptr };
if let Some(write_error) = emitter.write_error.take() {
Error::Io(write_error)
} else {
Error::Libyaml(unsafe { libyaml::Error::emit_error(&emitter.sys) })
}
}
}
unsafe fn write_handler(data: *mut c_void, buffer: *mut u8, size: u64) -> i32 {
let data = data.cast::<EmitterPinned>();
match io::Write::write_all(unsafe { &mut *(*data).write }, unsafe {
slice::from_raw_parts(buffer, size as usize)
}) {
Ok(()) => 1,
Err(err) => {
unsafe {
(*data).write_error = Some(err);
}
0
}
}
}
impl<'a> Drop for EmitterPinned<'a> {
fn drop(&mut self) {
unsafe { sys::yaml_emitter_delete(&mut self.sys) }
}
}

162
vendor/serde_yaml/src/libyaml/error.rs vendored Normal file
View File

@@ -0,0 +1,162 @@
use crate::libyaml::cstr::CStr;
use std::fmt::{self, Debug, Display};
use std::mem::MaybeUninit;
use std::ptr::NonNull;
use unsafe_libyaml as sys;
pub(crate) type Result<T> = std::result::Result<T, Error>;
pub(crate) struct Error {
kind: sys::yaml_error_type_t,
problem: CStr<'static>,
problem_offset: u64,
problem_mark: Mark,
context: Option<CStr<'static>>,
context_mark: Mark,
}
impl Error {
pub unsafe fn parse_error(parser: *const sys::yaml_parser_t) -> Self {
Error {
kind: unsafe { (*parser).error },
problem: match NonNull::new(unsafe { (*parser).problem as *mut _ }) {
Some(problem) => unsafe { CStr::from_ptr(problem) },
None => CStr::from_bytes_with_nul(b"libyaml parser failed but there is no error\0"),
},
problem_offset: unsafe { (*parser).problem_offset },
problem_mark: Mark {
sys: unsafe { (*parser).problem_mark },
},
context: match NonNull::new(unsafe { (*parser).context as *mut _ }) {
Some(context) => Some(unsafe { CStr::from_ptr(context) }),
None => None,
},
context_mark: Mark {
sys: unsafe { (*parser).context_mark },
},
}
}
pub unsafe fn emit_error(emitter: *const sys::yaml_emitter_t) -> Self {
Error {
kind: unsafe { (*emitter).error },
problem: match NonNull::new(unsafe { (*emitter).problem as *mut _ }) {
Some(problem) => unsafe { CStr::from_ptr(problem) },
None => {
CStr::from_bytes_with_nul(b"libyaml emitter failed but there is no error\0")
}
},
problem_offset: 0,
problem_mark: Mark {
sys: unsafe { MaybeUninit::<sys::yaml_mark_t>::zeroed().assume_init() },
},
context: None,
context_mark: Mark {
sys: unsafe { MaybeUninit::<sys::yaml_mark_t>::zeroed().assume_init() },
},
}
}
pub fn mark(&self) -> Mark {
self.problem_mark
}
}
impl Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "{}", self.problem)?;
if self.problem_mark.sys.line != 0 || self.problem_mark.sys.column != 0 {
write!(formatter, " at {}", self.problem_mark)?;
} else if self.problem_offset != 0 {
write!(formatter, " at position {}", self.problem_offset)?;
}
if let Some(context) = &self.context {
write!(formatter, ", {}", context)?;
if (self.context_mark.sys.line != 0 || self.context_mark.sys.column != 0)
&& (self.context_mark.sys.line != self.problem_mark.sys.line
|| self.context_mark.sys.column != self.problem_mark.sys.column)
{
write!(formatter, " at {}", self.context_mark)?;
}
}
Ok(())
}
}
impl Debug for Error {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let mut formatter = formatter.debug_struct("Error");
if let Some(kind) = match self.kind {
sys::YAML_MEMORY_ERROR => Some("MEMORY"),
sys::YAML_READER_ERROR => Some("READER"),
sys::YAML_SCANNER_ERROR => Some("SCANNER"),
sys::YAML_PARSER_ERROR => Some("PARSER"),
sys::YAML_COMPOSER_ERROR => Some("COMPOSER"),
sys::YAML_WRITER_ERROR => Some("WRITER"),
sys::YAML_EMITTER_ERROR => Some("EMITTER"),
_ => None,
} {
formatter.field("kind", &format_args!("{}", kind));
}
formatter.field("problem", &self.problem);
if self.problem_mark.sys.line != 0 || self.problem_mark.sys.column != 0 {
formatter.field("problem_mark", &self.problem_mark);
} else if self.problem_offset != 0 {
formatter.field("problem_offset", &self.problem_offset);
}
if let Some(context) = &self.context {
formatter.field("context", context);
if self.context_mark.sys.line != 0 || self.context_mark.sys.column != 0 {
formatter.field("context_mark", &self.context_mark);
}
}
formatter.finish()
}
}
#[derive(Copy, Clone)]
pub(crate) struct Mark {
pub(super) sys: sys::yaml_mark_t,
}
impl Mark {
pub fn index(&self) -> u64 {
self.sys.index
}
pub fn line(&self) -> u64 {
self.sys.line
}
pub fn column(&self) -> u64 {
self.sys.column
}
}
impl Display for Mark {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
if self.sys.line != 0 || self.sys.column != 0 {
write!(
formatter,
"line {} column {}",
self.sys.line + 1,
self.sys.column + 1,
)
} else {
write!(formatter, "position {}", self.sys.index)
}
}
}
impl Debug for Mark {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let mut formatter = formatter.debug_struct("Mark");
if self.sys.line != 0 || self.sys.column != 0 {
formatter.field("line", &(self.sys.line + 1));
formatter.field("column", &(self.sys.column + 1));
} else {
formatter.field("index", &self.sys.index);
}
formatter.finish()
}
}

8
vendor/serde_yaml/src/libyaml/mod.rs vendored Normal file
View File

@@ -0,0 +1,8 @@
mod cstr;
pub mod emitter;
pub mod error;
pub mod parser;
pub mod tag;
mod util;
use self::error::Error;

201
vendor/serde_yaml/src/libyaml/parser.rs vendored Normal file
View File

@@ -0,0 +1,201 @@
use crate::libyaml::cstr::{self, CStr};
use crate::libyaml::error::{Error, Mark, Result};
use crate::libyaml::tag::Tag;
use crate::libyaml::util::Owned;
use std::borrow::Cow;
use std::fmt::{self, Debug};
use std::mem::MaybeUninit;
use std::ptr::{addr_of_mut, NonNull};
use std::slice;
use unsafe_libyaml as sys;
pub(crate) struct Parser<'input> {
pin: Owned<ParserPinned<'input>>,
}
struct ParserPinned<'input> {
sys: sys::yaml_parser_t,
input: Cow<'input, [u8]>,
}
#[derive(Debug)]
pub(crate) enum Event<'input> {
StreamStart,
StreamEnd,
DocumentStart,
DocumentEnd,
Alias(Anchor),
Scalar(Scalar<'input>),
SequenceStart(SequenceStart),
SequenceEnd,
MappingStart(MappingStart),
MappingEnd,
}
pub(crate) struct Scalar<'input> {
pub anchor: Option<Anchor>,
pub tag: Option<Tag>,
pub value: Box<[u8]>,
pub style: ScalarStyle,
pub repr: Option<&'input [u8]>,
}
#[derive(Debug)]
pub(crate) struct SequenceStart {
pub anchor: Option<Anchor>,
pub tag: Option<Tag>,
}
#[derive(Debug)]
pub(crate) struct MappingStart {
pub anchor: Option<Anchor>,
pub tag: Option<Tag>,
}
#[derive(Ord, PartialOrd, Eq, PartialEq)]
pub(crate) struct Anchor(Box<[u8]>);
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub(crate) enum ScalarStyle {
Plain,
SingleQuoted,
DoubleQuoted,
Literal,
Folded,
}
impl<'input> Parser<'input> {
pub fn new(input: Cow<'input, [u8]>) -> Parser<'input> {
let owned = Owned::<ParserPinned>::new_uninit();
let pin = unsafe {
let parser = addr_of_mut!((*owned.ptr).sys);
if sys::yaml_parser_initialize(parser).fail {
panic!("malloc error: {}", Error::parse_error(parser));
}
sys::yaml_parser_set_encoding(parser, sys::YAML_UTF8_ENCODING);
sys::yaml_parser_set_input_string(parser, input.as_ptr(), input.len() as u64);
addr_of_mut!((*owned.ptr).input).write(input);
Owned::assume_init(owned)
};
Parser { pin }
}
pub fn next(&mut self) -> Result<(Event<'input>, Mark)> {
let mut event = MaybeUninit::<sys::yaml_event_t>::uninit();
unsafe {
let parser = addr_of_mut!((*self.pin.ptr).sys);
if (*parser).error != sys::YAML_NO_ERROR {
return Err(Error::parse_error(parser));
}
let event = event.as_mut_ptr();
if sys::yaml_parser_parse(parser, event).fail {
return Err(Error::parse_error(parser));
}
let ret = convert_event(&*event, &(*self.pin.ptr).input);
let mark = Mark {
sys: (*event).start_mark,
};
sys::yaml_event_delete(event);
Ok((ret, mark))
}
}
}
unsafe fn convert_event<'input>(
sys: &sys::yaml_event_t,
input: &Cow<'input, [u8]>,
) -> Event<'input> {
match sys.type_ {
sys::YAML_STREAM_START_EVENT => Event::StreamStart,
sys::YAML_STREAM_END_EVENT => Event::StreamEnd,
sys::YAML_DOCUMENT_START_EVENT => Event::DocumentStart,
sys::YAML_DOCUMENT_END_EVENT => Event::DocumentEnd,
sys::YAML_ALIAS_EVENT => {
Event::Alias(unsafe { optional_anchor(sys.data.alias.anchor) }.unwrap())
}
sys::YAML_SCALAR_EVENT => Event::Scalar(Scalar {
anchor: unsafe { optional_anchor(sys.data.scalar.anchor) },
tag: unsafe { optional_tag(sys.data.scalar.tag) },
value: Box::from(unsafe {
slice::from_raw_parts(sys.data.scalar.value, sys.data.scalar.length as usize)
}),
style: match unsafe { sys.data.scalar.style } {
sys::YAML_PLAIN_SCALAR_STYLE => ScalarStyle::Plain,
sys::YAML_SINGLE_QUOTED_SCALAR_STYLE => ScalarStyle::SingleQuoted,
sys::YAML_DOUBLE_QUOTED_SCALAR_STYLE => ScalarStyle::DoubleQuoted,
sys::YAML_LITERAL_SCALAR_STYLE => ScalarStyle::Literal,
sys::YAML_FOLDED_SCALAR_STYLE => ScalarStyle::Folded,
sys::YAML_ANY_SCALAR_STYLE | _ => unreachable!(),
},
repr: if let Cow::Borrowed(input) = input {
Some(&input[sys.start_mark.index as usize..sys.end_mark.index as usize])
} else {
None
},
}),
sys::YAML_SEQUENCE_START_EVENT => Event::SequenceStart(SequenceStart {
anchor: unsafe { optional_anchor(sys.data.sequence_start.anchor) },
tag: unsafe { optional_tag(sys.data.sequence_start.tag) },
}),
sys::YAML_SEQUENCE_END_EVENT => Event::SequenceEnd,
sys::YAML_MAPPING_START_EVENT => Event::MappingStart(MappingStart {
anchor: unsafe { optional_anchor(sys.data.mapping_start.anchor) },
tag: unsafe { optional_tag(sys.data.mapping_start.tag) },
}),
sys::YAML_MAPPING_END_EVENT => Event::MappingEnd,
sys::YAML_NO_EVENT => unreachable!(),
_ => unimplemented!(),
}
}
unsafe fn optional_anchor(anchor: *const u8) -> Option<Anchor> {
let ptr = NonNull::new(anchor as *mut i8)?;
let cstr = unsafe { CStr::from_ptr(ptr) };
Some(Anchor(Box::from(cstr.to_bytes())))
}
unsafe fn optional_tag(tag: *const u8) -> Option<Tag> {
let ptr = NonNull::new(tag as *mut i8)?;
let cstr = unsafe { CStr::from_ptr(ptr) };
Some(Tag(Box::from(cstr.to_bytes())))
}
impl<'input> Debug for Scalar<'input> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let Scalar {
anchor,
tag,
value,
style,
repr: _,
} = self;
struct LossySlice<'a>(&'a [u8]);
impl<'a> Debug for LossySlice<'a> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
cstr::debug_lossy(self.0, formatter)
}
}
formatter
.debug_struct("Scalar")
.field("anchor", anchor)
.field("tag", tag)
.field("value", &LossySlice(value))
.field("style", style)
.finish()
}
}
impl Debug for Anchor {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
cstr::debug_lossy(&self.0, formatter)
}
}
impl<'input> Drop for ParserPinned<'input> {
fn drop(&mut self) {
unsafe { sys::yaml_parser_delete(&mut self.sys) }
}
}

38
vendor/serde_yaml/src/libyaml/tag.rs vendored Normal file
View File

@@ -0,0 +1,38 @@
use crate::libyaml::cstr;
use std::fmt::{self, Debug};
use std::ops::Deref;
#[derive(Ord, PartialOrd, Eq, PartialEq)]
pub(crate) struct Tag(pub(in crate::libyaml) Box<[u8]>);
impl Tag {
pub const NULL: &'static str = "tag:yaml.org,2002:null";
pub const BOOL: &'static str = "tag:yaml.org,2002:bool";
pub const INT: &'static str = "tag:yaml.org,2002:int";
pub const FLOAT: &'static str = "tag:yaml.org,2002:float";
}
impl Tag {
pub fn starts_with(&self, prefix: &str) -> bool {
self.0.starts_with(prefix.as_bytes())
}
}
impl PartialEq<str> for Tag {
fn eq(&self, other: &str) -> bool {
*self.0 == *other.as_bytes()
}
}
impl Deref for Tag {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Debug for Tag {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
cstr::debug_lossy(&self.0, formatter)
}
}

48
vendor/serde_yaml/src/libyaml/util.rs vendored Normal file
View File

@@ -0,0 +1,48 @@
use std::marker::PhantomData;
use std::mem::{self, MaybeUninit};
use std::ops::Deref;
use std::ptr::{addr_of, NonNull};
pub(crate) struct Owned<T, Init = T> {
ptr: NonNull<T>,
marker: PhantomData<NonNull<Init>>,
}
impl<T> Owned<T> {
pub fn new_uninit() -> Owned<MaybeUninit<T>, T> {
// FIXME: use Box::new_uninit when stable
let boxed = Box::new(MaybeUninit::<T>::uninit());
Owned {
ptr: unsafe { NonNull::new_unchecked(Box::into_raw(boxed)) },
marker: PhantomData,
}
}
pub unsafe fn assume_init(definitely_init: Owned<MaybeUninit<T>, T>) -> Owned<T> {
let ptr = definitely_init.ptr;
mem::forget(definitely_init);
Owned {
ptr: ptr.cast(),
marker: PhantomData,
}
}
}
#[repr(transparent)]
pub(crate) struct InitPtr<T> {
pub ptr: *mut T,
}
impl<T, Init> Deref for Owned<T, Init> {
type Target = InitPtr<Init>;
fn deref(&self) -> &Self::Target {
unsafe { &*addr_of!(self.ptr).cast::<InitPtr<Init>>() }
}
}
impl<T, Init> Drop for Owned<T, Init> {
fn drop(&mut self) {
let _ = unsafe { Box::from_raw(self.ptr.as_ptr()) };
}
}

119
vendor/serde_yaml/src/loader.rs vendored Normal file
View File

@@ -0,0 +1,119 @@
use crate::de::{Event, Progress};
use crate::error::{self, Error, ErrorImpl, Result};
use crate::libyaml::error::Mark;
use crate::libyaml::parser::{Event as YamlEvent, Parser};
use std::borrow::Cow;
use std::collections::BTreeMap;
use std::sync::Arc;
pub(crate) struct Loader<'input> {
parser: Option<Parser<'input>>,
document_count: usize,
}
pub(crate) struct Document<'input> {
pub events: Vec<(Event<'input>, Mark)>,
pub error: Option<Arc<ErrorImpl>>,
/// Map from alias id to index in events.
pub aliases: BTreeMap<usize, usize>,
}
impl<'input> Loader<'input> {
pub fn new(progress: Progress<'input>) -> Result<Self> {
let input = match progress {
Progress::Str(s) => Cow::Borrowed(s.as_bytes()),
Progress::Slice(bytes) => Cow::Borrowed(bytes),
Progress::Read(mut rdr) => {
let mut buffer = Vec::new();
if let Err(io_error) = rdr.read_to_end(&mut buffer) {
return Err(error::new(ErrorImpl::Io(io_error)));
}
Cow::Owned(buffer)
}
Progress::Iterable(_) | Progress::Document(_) => unreachable!(),
Progress::Fail(err) => return Err(error::shared(err)),
};
Ok(Loader {
parser: Some(Parser::new(input)),
document_count: 0,
})
}
pub fn next_document(&mut self) -> Option<Document<'input>> {
let parser = match &mut self.parser {
Some(parser) => parser,
None => return None,
};
let first = self.document_count == 0;
self.document_count += 1;
let mut anchors = BTreeMap::new();
let mut document = Document {
events: Vec::new(),
error: None,
aliases: BTreeMap::new(),
};
loop {
let (event, mark) = match parser.next() {
Ok((event, mark)) => (event, mark),
Err(err) => {
document.error = Some(Error::from(err).shared());
return Some(document);
}
};
let event = match event {
YamlEvent::StreamStart => continue,
YamlEvent::StreamEnd => {
self.parser = None;
return if first {
if document.events.is_empty() {
document.events.push((Event::Void, mark));
}
Some(document)
} else {
None
};
}
YamlEvent::DocumentStart => continue,
YamlEvent::DocumentEnd => return Some(document),
YamlEvent::Alias(alias) => match anchors.get(&alias) {
Some(id) => Event::Alias(*id),
None => {
document.error = Some(error::new(ErrorImpl::UnknownAnchor(mark)).shared());
return Some(document);
}
},
YamlEvent::Scalar(mut scalar) => {
if let Some(anchor) = scalar.anchor.take() {
let id = anchors.len();
anchors.insert(anchor, id);
document.aliases.insert(id, document.events.len());
}
Event::Scalar(scalar)
}
YamlEvent::SequenceStart(mut sequence_start) => {
if let Some(anchor) = sequence_start.anchor.take() {
let id = anchors.len();
anchors.insert(anchor, id);
document.aliases.insert(id, document.events.len());
}
Event::SequenceStart(sequence_start)
}
YamlEvent::SequenceEnd => Event::SequenceEnd,
YamlEvent::MappingStart(mut mapping_start) => {
if let Some(anchor) = mapping_start.anchor.take() {
let id = anchors.len();
anchors.insert(anchor, id);
document.aliases.insert(id, document.events.len());
}
Event::MappingStart(mapping_start)
}
YamlEvent::MappingEnd => Event::MappingEnd,
};
document.events.push((event, mark));
}
}
}

851
vendor/serde_yaml/src/mapping.rs vendored Normal file
View File

@@ -0,0 +1,851 @@
//! A YAML mapping and its iterator types.
use crate::{private, Value};
use indexmap::IndexMap;
use serde::{Deserialize, Deserializer, Serialize};
use std::cmp::Ordering;
use std::collections::hash_map::DefaultHasher;
use std::fmt::{self, Display};
use std::hash::{Hash, Hasher};
use std::mem;
/// A YAML mapping in which the keys and values are both `serde_yaml::Value`.
#[derive(Clone, Default, Eq, PartialEq)]
pub struct Mapping {
map: IndexMap<Value, Value>,
}
impl Mapping {
/// Creates an empty YAML map.
#[inline]
pub fn new() -> Self {
Self::default()
}
/// Creates an empty YAML map with the given initial capacity.
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
Mapping {
map: IndexMap::with_capacity(capacity),
}
}
/// Reserves capacity for at least `additional` more elements to be inserted
/// into the map. The map may reserve more space to avoid frequent
/// allocations.
///
/// # Panics
///
/// Panics if the new allocation size overflows `usize`.
#[inline]
pub fn reserve(&mut self, additional: usize) {
self.map.reserve(additional);
}
/// Shrinks the capacity of the map as much as possible. It will drop down
/// as much as possible while maintaining the internal rules and possibly
/// leaving some space in accordance with the resize policy.
#[inline]
pub fn shrink_to_fit(&mut self) {
self.map.shrink_to_fit();
}
/// Inserts a key-value pair into the map. If the key already existed, the
/// old value is returned.
#[inline]
pub fn insert(&mut self, k: Value, v: Value) -> Option<Value> {
self.map.insert(k, v)
}
/// Checks if the map contains the given key.
#[inline]
pub fn contains_key<I: Index>(&self, index: I) -> bool {
index.is_key_into(self)
}
/// Returns the value corresponding to the key in the map.
#[inline]
pub fn get<I: Index>(&self, index: I) -> Option<&Value> {
index.index_into(self)
}
/// Returns the mutable reference corresponding to the key in the map.
#[inline]
pub fn get_mut<I: Index>(&mut self, index: I) -> Option<&mut Value> {
index.index_into_mut(self)
}
/// Gets the given key's corresponding entry in the map for insertion and/or
/// in-place manipulation.
#[inline]
pub fn entry(&mut self, k: Value) -> Entry {
match self.map.entry(k) {
indexmap::map::Entry::Occupied(occupied) => Entry::Occupied(OccupiedEntry { occupied }),
indexmap::map::Entry::Vacant(vacant) => Entry::Vacant(VacantEntry { vacant }),
}
}
/// Removes and returns the value corresponding to the key from the map.
///
/// This is equivalent to [`.swap_remove(index)`][Self::swap_remove],
/// replacing this entry's position with the last element. If you need to
/// preserve the relative order of the keys in the map, use
/// [`.shift_remove(key)`][Self::shift_remove] instead.
#[inline]
pub fn remove<I: Index>(&mut self, index: I) -> Option<Value> {
self.swap_remove(index)
}
/// Remove and return the key-value pair.
///
/// This is equivalent to [`.swap_remove_entry(index)`][Self::swap_remove_entry],
/// replacing this entry's position with the last element. If you need to
/// preserve the relative order of the keys in the map, use
/// [`.shift_remove_entry(key)`][Self::shift_remove_entry] instead.
#[inline]
pub fn remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)> {
self.swap_remove_entry(index)
}
/// Removes and returns the value corresponding to the key from the map.
///
/// Like [`Vec::swap_remove`], the entry is removed by swapping it with the
/// last element of the map and popping it off. This perturbs the position
/// of what used to be the last element!
#[inline]
pub fn swap_remove<I: Index>(&mut self, index: I) -> Option<Value> {
index.swap_remove_from(self)
}
/// Remove and return the key-value pair.
///
/// Like [`Vec::swap_remove`], the entry is removed by swapping it with the
/// last element of the map and popping it off. This perturbs the position
/// of what used to be the last element!
#[inline]
pub fn swap_remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)> {
index.swap_remove_entry_from(self)
}
/// Removes and returns the value corresponding to the key from the map.
///
/// Like [`Vec::remove`], the entry is removed by shifting all of the
/// elements that follow it, preserving their relative order. This perturbs
/// the index of all of those elements!
#[inline]
pub fn shift_remove<I: Index>(&mut self, index: I) -> Option<Value> {
index.shift_remove_from(self)
}
/// Remove and return the key-value pair.
///
/// Like [`Vec::remove`], the entry is removed by shifting all of the
/// elements that follow it, preserving their relative order. This perturbs
/// the index of all of those elements!
#[inline]
pub fn shift_remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)> {
index.shift_remove_entry_from(self)
}
/// Scan through each key-value pair in the map and keep those where the
/// closure `keep` returns true.
#[inline]
pub fn retain<F>(&mut self, keep: F)
where
F: FnMut(&Value, &mut Value) -> bool,
{
self.map.retain(keep);
}
/// Returns the maximum number of key-value pairs the map can hold without
/// reallocating.
#[inline]
pub fn capacity(&self) -> usize {
self.map.capacity()
}
/// Returns the number of key-value pairs in the map.
#[inline]
pub fn len(&self) -> usize {
self.map.len()
}
/// Returns whether the map is currently empty.
#[inline]
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
/// Clears the map of all key-value pairs.
#[inline]
pub fn clear(&mut self) {
self.map.clear();
}
/// Returns a double-ended iterator visiting all key-value pairs in order of
/// insertion. Iterator element type is `(&'a Value, &'a Value)`.
#[inline]
pub fn iter(&self) -> Iter {
Iter {
iter: self.map.iter(),
}
}
/// Returns a double-ended iterator visiting all key-value pairs in order of
/// insertion. Iterator element type is `(&'a Value, &'a mut ValuE)`.
#[inline]
pub fn iter_mut(&mut self) -> IterMut {
IterMut {
iter: self.map.iter_mut(),
}
}
/// Return an iterator over the keys of the map.
pub fn keys(&self) -> Keys {
Keys {
iter: self.map.keys(),
}
}
/// Return an owning iterator over the keys of the map.
pub fn into_keys(self) -> IntoKeys {
IntoKeys {
iter: self.map.into_keys(),
}
}
/// Return an iterator over the values of the map.
pub fn values(&self) -> Values {
Values {
iter: self.map.values(),
}
}
/// Return an iterator over mutable references to the values of the map.
pub fn values_mut(&mut self) -> ValuesMut {
ValuesMut {
iter: self.map.values_mut(),
}
}
/// Return an owning iterator over the values of the map.
pub fn into_values(self) -> IntoValues {
IntoValues {
iter: self.map.into_values(),
}
}
}
/// A type that can be used to index into a `serde_yaml::Mapping`. See the
/// methods `get`, `get_mut`, `contains_key`, and `remove` of `Value`.
///
/// This trait is sealed and cannot be implemented for types outside of
/// `serde_yaml`.
pub trait Index: private::Sealed {
#[doc(hidden)]
fn is_key_into(&self, v: &Mapping) -> bool;
#[doc(hidden)]
fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value>;
#[doc(hidden)]
fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value>;
#[doc(hidden)]
fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value>;
#[doc(hidden)]
fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>;
#[doc(hidden)]
fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value>;
#[doc(hidden)]
fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>;
}
struct HashLikeValue<'a>(&'a str);
impl<'a> indexmap::Equivalent<Value> for HashLikeValue<'a> {
fn equivalent(&self, key: &Value) -> bool {
match key {
Value::String(string) => self.0 == string,
_ => false,
}
}
}
// NOTE: This impl must be consistent with Value's Hash impl.
impl<'a> Hash for HashLikeValue<'a> {
fn hash<H: Hasher>(&self, state: &mut H) {
const STRING: Value = Value::String(String::new());
mem::discriminant(&STRING).hash(state);
self.0.hash(state);
}
}
impl Index for Value {
fn is_key_into(&self, v: &Mapping) -> bool {
v.map.contains_key(self)
}
fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value> {
v.map.get(self)
}
fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
v.map.get_mut(self)
}
fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
v.map.swap_remove(self)
}
fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
v.map.swap_remove_entry(self)
}
fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
v.map.shift_remove(self)
}
fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
v.map.shift_remove_entry(self)
}
}
impl Index for str {
fn is_key_into(&self, v: &Mapping) -> bool {
v.map.contains_key(&HashLikeValue(self))
}
fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value> {
v.map.get(&HashLikeValue(self))
}
fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
v.map.get_mut(&HashLikeValue(self))
}
fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
v.map.swap_remove(&HashLikeValue(self))
}
fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
v.map.swap_remove_entry(&HashLikeValue(self))
}
fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
v.map.shift_remove(&HashLikeValue(self))
}
fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
v.map.shift_remove_entry(&HashLikeValue(self))
}
}
impl Index for String {
fn is_key_into(&self, v: &Mapping) -> bool {
self.as_str().is_key_into(v)
}
fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value> {
self.as_str().index_into(v)
}
fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
self.as_str().index_into_mut(v)
}
fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
self.as_str().swap_remove_from(v)
}
fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
self.as_str().swap_remove_entry_from(v)
}
fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
self.as_str().shift_remove_from(v)
}
fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
self.as_str().shift_remove_entry_from(v)
}
}
impl<T> Index for &T
where
T: ?Sized + Index,
{
fn is_key_into(&self, v: &Mapping) -> bool {
(**self).is_key_into(v)
}
fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value> {
(**self).index_into(v)
}
fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
(**self).index_into_mut(v)
}
fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
(**self).swap_remove_from(v)
}
fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
(**self).swap_remove_entry_from(v)
}
fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
(**self).shift_remove_from(v)
}
fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
(**self).shift_remove_entry_from(v)
}
}
#[allow(clippy::derived_hash_with_manual_eq)]
impl Hash for Mapping {
fn hash<H: Hasher>(&self, state: &mut H) {
// Hash the kv pairs in a way that is not sensitive to their order.
let mut xor = 0;
for (k, v) in self {
let mut hasher = DefaultHasher::new();
k.hash(&mut hasher);
v.hash(&mut hasher);
xor ^= hasher.finish();
}
xor.hash(state);
}
}
impl PartialOrd for Mapping {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
let mut self_entries = Vec::from_iter(self);
let mut other_entries = Vec::from_iter(other);
// Sort in an arbitrary order that is consistent with Value's PartialOrd
// impl.
fn total_cmp(a: &Value, b: &Value) -> Ordering {
match (a, b) {
(Value::Null, Value::Null) => Ordering::Equal,
(Value::Null, _) => Ordering::Less,
(_, Value::Null) => Ordering::Greater,
(Value::Bool(a), Value::Bool(b)) => a.cmp(b),
(Value::Bool(_), _) => Ordering::Less,
(_, Value::Bool(_)) => Ordering::Greater,
(Value::Number(a), Value::Number(b)) => a.total_cmp(b),
(Value::Number(_), _) => Ordering::Less,
(_, Value::Number(_)) => Ordering::Greater,
(Value::String(a), Value::String(b)) => a.cmp(b),
(Value::String(_), _) => Ordering::Less,
(_, Value::String(_)) => Ordering::Greater,
(Value::Sequence(a), Value::Sequence(b)) => iter_cmp_by(a, b, total_cmp),
(Value::Sequence(_), _) => Ordering::Less,
(_, Value::Sequence(_)) => Ordering::Greater,
(Value::Mapping(a), Value::Mapping(b)) => {
iter_cmp_by(a, b, |(ak, av), (bk, bv)| {
total_cmp(ak, bk).then_with(|| total_cmp(av, bv))
})
}
(Value::Mapping(_), _) => Ordering::Less,
(_, Value::Mapping(_)) => Ordering::Greater,
(Value::Tagged(a), Value::Tagged(b)) => a
.tag
.cmp(&b.tag)
.then_with(|| total_cmp(&a.value, &b.value)),
}
}
fn iter_cmp_by<I, F>(this: I, other: I, mut cmp: F) -> Ordering
where
I: IntoIterator,
F: FnMut(I::Item, I::Item) -> Ordering,
{
let mut this = this.into_iter();
let mut other = other.into_iter();
loop {
let x = match this.next() {
None => {
if other.next().is_none() {
return Ordering::Equal;
} else {
return Ordering::Less;
}
}
Some(val) => val,
};
let y = match other.next() {
None => return Ordering::Greater,
Some(val) => val,
};
match cmp(x, y) {
Ordering::Equal => {}
non_eq => return non_eq,
}
}
}
// While sorting by map key, we get to assume that no two keys are
// equal, otherwise they wouldn't both be in the map. This is not a safe
// assumption outside of this situation.
let total_cmp = |&(a, _): &_, &(b, _): &_| total_cmp(a, b);
self_entries.sort_by(total_cmp);
other_entries.sort_by(total_cmp);
self_entries.partial_cmp(&other_entries)
}
}
impl<I> std::ops::Index<I> for Mapping
where
I: Index,
{
type Output = Value;
#[inline]
#[track_caller]
fn index(&self, index: I) -> &Value {
index.index_into(self).unwrap()
}
}
impl<I> std::ops::IndexMut<I> for Mapping
where
I: Index,
{
#[inline]
#[track_caller]
fn index_mut(&mut self, index: I) -> &mut Value {
index.index_into_mut(self).unwrap()
}
}
impl Extend<(Value, Value)> for Mapping {
#[inline]
fn extend<I: IntoIterator<Item = (Value, Value)>>(&mut self, iter: I) {
self.map.extend(iter);
}
}
impl FromIterator<(Value, Value)> for Mapping {
#[inline]
fn from_iter<I: IntoIterator<Item = (Value, Value)>>(iter: I) -> Self {
Mapping {
map: IndexMap::from_iter(iter),
}
}
}
macro_rules! delegate_iterator {
(($name:ident $($generics:tt)*) => $item:ty) => {
impl $($generics)* Iterator for $name $($generics)* {
type Item = $item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl $($generics)* ExactSizeIterator for $name $($generics)* {
#[inline]
fn len(&self) -> usize {
self.iter.len()
}
}
}
}
/// Iterator over `&serde_yaml::Mapping`.
pub struct Iter<'a> {
iter: indexmap::map::Iter<'a, Value, Value>,
}
delegate_iterator!((Iter<'a>) => (&'a Value, &'a Value));
impl<'a> IntoIterator for &'a Mapping {
type Item = (&'a Value, &'a Value);
type IntoIter = Iter<'a>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
Iter {
iter: self.map.iter(),
}
}
}
/// Iterator over `&mut serde_yaml::Mapping`.
pub struct IterMut<'a> {
iter: indexmap::map::IterMut<'a, Value, Value>,
}
delegate_iterator!((IterMut<'a>) => (&'a Value, &'a mut Value));
impl<'a> IntoIterator for &'a mut Mapping {
type Item = (&'a Value, &'a mut Value);
type IntoIter = IterMut<'a>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
IterMut {
iter: self.map.iter_mut(),
}
}
}
/// Iterator over `serde_yaml::Mapping` by value.
pub struct IntoIter {
iter: indexmap::map::IntoIter<Value, Value>,
}
delegate_iterator!((IntoIter) => (Value, Value));
impl IntoIterator for Mapping {
type Item = (Value, Value);
type IntoIter = IntoIter;
#[inline]
fn into_iter(self) -> Self::IntoIter {
IntoIter {
iter: self.map.into_iter(),
}
}
}
/// Iterator of the keys of a `&serde_yaml::Mapping`.
pub struct Keys<'a> {
iter: indexmap::map::Keys<'a, Value, Value>,
}
delegate_iterator!((Keys<'a>) => &'a Value);
/// Iterator of the keys of a `serde_yaml::Mapping`.
pub struct IntoKeys {
iter: indexmap::map::IntoKeys<Value, Value>,
}
delegate_iterator!((IntoKeys) => Value);
/// Iterator of the values of a `&serde_yaml::Mapping`.
pub struct Values<'a> {
iter: indexmap::map::Values<'a, Value, Value>,
}
delegate_iterator!((Values<'a>) => &'a Value);
/// Iterator of the values of a `&mut serde_yaml::Mapping`.
pub struct ValuesMut<'a> {
iter: indexmap::map::ValuesMut<'a, Value, Value>,
}
delegate_iterator!((ValuesMut<'a>) => &'a mut Value);
/// Iterator of the values of a `serde_yaml::Mapping`.
pub struct IntoValues {
iter: indexmap::map::IntoValues<Value, Value>,
}
delegate_iterator!((IntoValues) => Value);
/// Entry for an existing key-value pair or a vacant location to insert one.
pub enum Entry<'a> {
/// Existing slot with equivalent key.
Occupied(OccupiedEntry<'a>),
/// Vacant slot (no equivalent key in the map).
Vacant(VacantEntry<'a>),
}
/// A view into an occupied entry in a [`Mapping`]. It is part of the [`Entry`]
/// enum.
pub struct OccupiedEntry<'a> {
occupied: indexmap::map::OccupiedEntry<'a, Value, Value>,
}
/// A view into a vacant entry in a [`Mapping`]. It is part of the [`Entry`]
/// enum.
pub struct VacantEntry<'a> {
vacant: indexmap::map::VacantEntry<'a, Value, Value>,
}
impl<'a> Entry<'a> {
/// Returns a reference to this entry's key.
pub fn key(&self) -> &Value {
match self {
Entry::Vacant(e) => e.key(),
Entry::Occupied(e) => e.key(),
}
}
/// Ensures a value is in the entry by inserting the default if empty, and
/// returns a mutable reference to the value in the entry.
pub fn or_insert(self, default: Value) -> &'a mut Value {
match self {
Entry::Vacant(entry) => entry.insert(default),
Entry::Occupied(entry) => entry.into_mut(),
}
}
/// Ensures a value is in the entry by inserting the result of the default
/// function if empty, and returns a mutable reference to the value in the
/// entry.
pub fn or_insert_with<F>(self, default: F) -> &'a mut Value
where
F: FnOnce() -> Value,
{
match self {
Entry::Vacant(entry) => entry.insert(default()),
Entry::Occupied(entry) => entry.into_mut(),
}
}
/// Provides in-place mutable access to an occupied entry before any
/// potential inserts into the map.
pub fn and_modify<F>(self, f: F) -> Self
where
F: FnOnce(&mut Value),
{
match self {
Entry::Occupied(mut entry) => {
f(entry.get_mut());
Entry::Occupied(entry)
}
Entry::Vacant(entry) => Entry::Vacant(entry),
}
}
}
impl<'a> OccupiedEntry<'a> {
/// Gets a reference to the key in the entry.
#[inline]
pub fn key(&self) -> &Value {
self.occupied.key()
}
/// Gets a reference to the value in the entry.
#[inline]
pub fn get(&self) -> &Value {
self.occupied.get()
}
/// Gets a mutable reference to the value in the entry.
#[inline]
pub fn get_mut(&mut self) -> &mut Value {
self.occupied.get_mut()
}
/// Converts the entry into a mutable reference to its value.
#[inline]
pub fn into_mut(self) -> &'a mut Value {
self.occupied.into_mut()
}
/// Sets the value of the entry with the `OccupiedEntry`'s key, and returns
/// the entry's old value.
#[inline]
pub fn insert(&mut self, value: Value) -> Value {
self.occupied.insert(value)
}
/// Takes the value of the entry out of the map, and returns it.
#[inline]
pub fn remove(self) -> Value {
self.occupied.swap_remove()
}
/// Remove and return the key, value pair stored in the map for this entry.
#[inline]
pub fn remove_entry(self) -> (Value, Value) {
self.occupied.swap_remove_entry()
}
}
impl<'a> VacantEntry<'a> {
/// Gets a reference to the key that would be used when inserting a value
/// through the VacantEntry.
#[inline]
pub fn key(&self) -> &Value {
self.vacant.key()
}
/// Takes ownership of the key, leaving the entry vacant.
#[inline]
pub fn into_key(self) -> Value {
self.vacant.into_key()
}
/// Sets the value of the entry with the VacantEntry's key, and returns a
/// mutable reference to it.
#[inline]
pub fn insert(self, value: Value) -> &'a mut Value {
self.vacant.insert(value)
}
}
impl Serialize for Mapping {
#[inline]
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
use serde::ser::SerializeMap;
let mut map_serializer = serializer.serialize_map(Some(self.len()))?;
for (k, v) in self {
map_serializer.serialize_entry(k, v)?;
}
map_serializer.end()
}
}
impl<'de> Deserialize<'de> for Mapping {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct Visitor;
impl<'de> serde::de::Visitor<'de> for Visitor {
type Value = Mapping;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a YAML mapping")
}
#[inline]
fn visit_unit<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Mapping::new())
}
#[inline]
fn visit_map<A>(self, mut data: A) -> Result<Self::Value, A::Error>
where
A: serde::de::MapAccess<'de>,
{
let mut mapping = Mapping::new();
while let Some(key) = data.next_key()? {
match mapping.entry(key) {
Entry::Occupied(entry) => {
return Err(serde::de::Error::custom(DuplicateKeyError { entry }));
}
Entry::Vacant(entry) => {
let value = data.next_value()?;
entry.insert(value);
}
}
}
Ok(mapping)
}
}
deserializer.deserialize_map(Visitor)
}
}
struct DuplicateKeyError<'a> {
entry: OccupiedEntry<'a>,
}
impl<'a> Display for DuplicateKeyError<'a> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("duplicate entry ")?;
match self.entry.key() {
Value::Null => formatter.write_str("with null key"),
Value::Bool(boolean) => write!(formatter, "with key `{}`", boolean),
Value::Number(number) => write!(formatter, "with key {}", number),
Value::String(string) => write!(formatter, "with key {:?}", string),
Value::Sequence(_) | Value::Mapping(_) | Value::Tagged(_) => {
formatter.write_str("in YAML map")
}
}
}
}

561
vendor/serde_yaml/src/number.rs vendored Normal file
View File

@@ -0,0 +1,561 @@
use crate::de;
use crate::error::{self, Error, ErrorImpl};
use serde::de::{Unexpected, Visitor};
use serde::{forward_to_deserialize_any, Deserialize, Deserializer, Serialize, Serializer};
use std::cmp::Ordering;
use std::fmt::{self, Display};
use std::hash::{Hash, Hasher};
use std::str::FromStr;
/// Represents a YAML number, whether integer or floating point.
#[derive(Clone, PartialEq, PartialOrd)]
pub struct Number {
n: N,
}
// "N" is a prefix of "NegInt"... this is a false positive.
// https://github.com/Manishearth/rust-clippy/issues/1241
#[allow(clippy::enum_variant_names)]
#[derive(Copy, Clone)]
enum N {
PosInt(u64),
/// Always less than zero.
NegInt(i64),
/// May be infinite or NaN.
Float(f64),
}
impl Number {
/// Returns true if the `Number` is an integer between `i64::MIN` and
/// `i64::MAX`.
///
/// For any Number on which `is_i64` returns true, `as_i64` is guaranteed to
/// return the integer value.
///
/// ```
/// # fn main() -> serde_yaml::Result<()> {
/// let big = i64::MAX as u64 + 10;
/// let v: serde_yaml::Value = serde_yaml::from_str(r#"
/// a: 64
/// b: 9223372036854775817
/// c: 256.0
/// "#)?;
///
/// assert!(v["a"].is_i64());
///
/// // Greater than i64::MAX.
/// assert!(!v["b"].is_i64());
///
/// // Numbers with a decimal point are not considered integers.
/// assert!(!v["c"].is_i64());
/// # Ok(())
/// # }
/// ```
#[inline]
#[allow(clippy::cast_sign_loss)]
pub fn is_i64(&self) -> bool {
match self.n {
N::PosInt(v) => v <= i64::max_value() as u64,
N::NegInt(_) => true,
N::Float(_) => false,
}
}
/// Returns true if the `Number` is an integer between zero and `u64::MAX`.
///
/// For any Number on which `is_u64` returns true, `as_u64` is guaranteed to
/// return the integer value.
///
/// ```
/// # fn main() -> serde_yaml::Result<()> {
/// let v: serde_yaml::Value = serde_yaml::from_str(r#"
/// a: 64
/// b: -64
/// c: 256.0
/// "#)?;
///
/// assert!(v["a"].is_u64());
///
/// // Negative integer.
/// assert!(!v["b"].is_u64());
///
/// // Numbers with a decimal point are not considered integers.
/// assert!(!v["c"].is_u64());
/// # Ok(())
/// # }
/// ```
#[inline]
pub fn is_u64(&self) -> bool {
match self.n {
N::PosInt(_) => true,
N::NegInt(_) | N::Float(_) => false,
}
}
/// Returns true if the `Number` can be represented by f64.
///
/// For any Number on which `is_f64` returns true, `as_f64` is guaranteed to
/// return the floating point value.
///
/// Currently this function returns true if and only if both `is_i64` and
/// `is_u64` return false but this is not a guarantee in the future.
///
/// ```
/// # fn main() -> serde_yaml::Result<()> {
/// let v: serde_yaml::Value = serde_yaml::from_str(r#"
/// a: 256.0
/// b: 64
/// c: -64
/// "#)?;
///
/// assert!(v["a"].is_f64());
///
/// // Integers.
/// assert!(!v["b"].is_f64());
/// assert!(!v["c"].is_f64());
/// # Ok(())
/// # }
/// ```
#[inline]
pub fn is_f64(&self) -> bool {
match self.n {
N::Float(_) => true,
N::PosInt(_) | N::NegInt(_) => false,
}
}
/// If the `Number` is an integer, represent it as i64 if possible. Returns
/// None otherwise.
///
/// ```
/// # fn main() -> serde_yaml::Result<()> {
/// let big = i64::MAX as u64 + 10;
/// let v: serde_yaml::Value = serde_yaml::from_str(r#"
/// a: 64
/// b: 9223372036854775817
/// c: 256.0
/// "#)?;
///
/// assert_eq!(v["a"].as_i64(), Some(64));
/// assert_eq!(v["b"].as_i64(), None);
/// assert_eq!(v["c"].as_i64(), None);
/// # Ok(())
/// # }
/// ```
#[inline]
pub fn as_i64(&self) -> Option<i64> {
match self.n {
N::PosInt(n) => {
if n <= i64::max_value() as u64 {
Some(n as i64)
} else {
None
}
}
N::NegInt(n) => Some(n),
N::Float(_) => None,
}
}
/// If the `Number` is an integer, represent it as u64 if possible. Returns
/// None otherwise.
///
/// ```
/// # fn main() -> serde_yaml::Result<()> {
/// let v: serde_yaml::Value = serde_yaml::from_str(r#"
/// a: 64
/// b: -64
/// c: 256.0
/// "#)?;
///
/// assert_eq!(v["a"].as_u64(), Some(64));
/// assert_eq!(v["b"].as_u64(), None);
/// assert_eq!(v["c"].as_u64(), None);
/// # Ok(())
/// # }
/// ```
#[inline]
pub fn as_u64(&self) -> Option<u64> {
match self.n {
N::PosInt(n) => Some(n),
N::NegInt(_) | N::Float(_) => None,
}
}
/// Represents the number as f64 if possible. Returns None otherwise.
///
/// ```
/// # fn main() -> serde_yaml::Result<()> {
/// let v: serde_yaml::Value = serde_yaml::from_str(r#"
/// a: 256.0
/// b: 64
/// c: -64
/// "#)?;
///
/// assert_eq!(v["a"].as_f64(), Some(256.0));
/// assert_eq!(v["b"].as_f64(), Some(64.0));
/// assert_eq!(v["c"].as_f64(), Some(-64.0));
/// # Ok(())
/// # }
/// ```
///
/// ```
/// # fn main() -> serde_yaml::Result<()> {
/// let v: serde_yaml::Value = serde_yaml::from_str(".inf")?;
/// assert_eq!(v.as_f64(), Some(f64::INFINITY));
///
/// let v: serde_yaml::Value = serde_yaml::from_str("-.inf")?;
/// assert_eq!(v.as_f64(), Some(f64::NEG_INFINITY));
///
/// let v: serde_yaml::Value = serde_yaml::from_str(".nan")?;
/// assert!(v.as_f64().unwrap().is_nan());
/// # Ok(())
/// # }
/// ```
#[inline]
pub fn as_f64(&self) -> Option<f64> {
match self.n {
N::PosInt(n) => Some(n as f64),
N::NegInt(n) => Some(n as f64),
N::Float(n) => Some(n),
}
}
/// Returns true if this value is NaN and false otherwise.
///
/// ```
/// # use serde_yaml::Number;
/// #
/// assert!(!Number::from(256.0).is_nan());
///
/// assert!(Number::from(f64::NAN).is_nan());
///
/// assert!(!Number::from(f64::INFINITY).is_nan());
///
/// assert!(!Number::from(f64::NEG_INFINITY).is_nan());
///
/// assert!(!Number::from(1).is_nan());
/// ```
#[inline]
pub fn is_nan(&self) -> bool {
match self.n {
N::PosInt(_) | N::NegInt(_) => false,
N::Float(f) => f.is_nan(),
}
}
/// Returns true if this value is positive infinity or negative infinity and
/// false otherwise.
///
/// ```
/// # use serde_yaml::Number;
/// #
/// assert!(!Number::from(256.0).is_infinite());
///
/// assert!(!Number::from(f64::NAN).is_infinite());
///
/// assert!(Number::from(f64::INFINITY).is_infinite());
///
/// assert!(Number::from(f64::NEG_INFINITY).is_infinite());
///
/// assert!(!Number::from(1).is_infinite());
/// ```
#[inline]
pub fn is_infinite(&self) -> bool {
match self.n {
N::PosInt(_) | N::NegInt(_) => false,
N::Float(f) => f.is_infinite(),
}
}
/// Returns true if this number is neither infinite nor NaN.
///
/// ```
/// # use serde_yaml::Number;
/// #
/// assert!(Number::from(256.0).is_finite());
///
/// assert!(!Number::from(f64::NAN).is_finite());
///
/// assert!(!Number::from(f64::INFINITY).is_finite());
///
/// assert!(!Number::from(f64::NEG_INFINITY).is_finite());
///
/// assert!(Number::from(1).is_finite());
/// ```
#[inline]
pub fn is_finite(&self) -> bool {
match self.n {
N::PosInt(_) | N::NegInt(_) => true,
N::Float(f) => f.is_finite(),
}
}
}
impl Display for Number {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
match self.n {
N::PosInt(i) => formatter.write_str(itoa::Buffer::new().format(i)),
N::NegInt(i) => formatter.write_str(itoa::Buffer::new().format(i)),
N::Float(f) if f.is_nan() => formatter.write_str(".nan"),
N::Float(f) if f.is_infinite() => {
if f.is_sign_negative() {
formatter.write_str("-.inf")
} else {
formatter.write_str(".inf")
}
}
N::Float(f) => formatter.write_str(ryu::Buffer::new().format_finite(f)),
}
}
}
impl FromStr for Number {
type Err = Error;
fn from_str(repr: &str) -> Result<Self, Self::Err> {
if let Ok(result) = de::visit_int(NumberVisitor, repr) {
return result;
}
if !de::digits_but_not_number(repr) {
if let Some(float) = de::parse_f64(repr) {
return Ok(float.into());
}
}
Err(error::new(ErrorImpl::FailedToParseNumber))
}
}
impl PartialEq for N {
fn eq(&self, other: &N) -> bool {
match (*self, *other) {
(N::PosInt(a), N::PosInt(b)) => a == b,
(N::NegInt(a), N::NegInt(b)) => a == b,
(N::Float(a), N::Float(b)) => {
if a.is_nan() && b.is_nan() {
// YAML only has one NaN;
// the bit representation isn't preserved
true
} else {
a == b
}
}
_ => false,
}
}
}
impl PartialOrd for N {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
match (*self, *other) {
(N::Float(a), N::Float(b)) => {
if a.is_nan() && b.is_nan() {
// YAML only has one NaN
Some(Ordering::Equal)
} else {
a.partial_cmp(&b)
}
}
_ => Some(self.total_cmp(other)),
}
}
}
impl N {
fn total_cmp(&self, other: &Self) -> Ordering {
match (*self, *other) {
(N::PosInt(a), N::PosInt(b)) => a.cmp(&b),
(N::NegInt(a), N::NegInt(b)) => a.cmp(&b),
// negint is always less than zero
(N::NegInt(_), N::PosInt(_)) => Ordering::Less,
(N::PosInt(_), N::NegInt(_)) => Ordering::Greater,
(N::Float(a), N::Float(b)) => a.partial_cmp(&b).unwrap_or_else(|| {
// arbitrarily sort the NaN last
if !a.is_nan() {
Ordering::Less
} else if !b.is_nan() {
Ordering::Greater
} else {
Ordering::Equal
}
}),
// arbitrarily sort integers below floats
// FIXME: maybe something more sensible?
(_, N::Float(_)) => Ordering::Less,
(N::Float(_), _) => Ordering::Greater,
}
}
}
impl Number {
pub(crate) fn total_cmp(&self, other: &Self) -> Ordering {
self.n.total_cmp(&other.n)
}
}
impl Serialize for Number {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self.n {
N::PosInt(i) => serializer.serialize_u64(i),
N::NegInt(i) => serializer.serialize_i64(i),
N::Float(f) => serializer.serialize_f64(f),
}
}
}
struct NumberVisitor;
impl<'de> Visitor<'de> for NumberVisitor {
type Value = Number;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a number")
}
#[inline]
fn visit_i64<E>(self, value: i64) -> Result<Number, E> {
Ok(value.into())
}
#[inline]
fn visit_u64<E>(self, value: u64) -> Result<Number, E> {
Ok(value.into())
}
#[inline]
fn visit_f64<E>(self, value: f64) -> Result<Number, E> {
Ok(value.into())
}
}
impl<'de> Deserialize<'de> for Number {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Number, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(NumberVisitor)
}
}
impl<'de> Deserializer<'de> for Number {
type Error = Error;
#[inline]
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
match self.n {
N::PosInt(i) => visitor.visit_u64(i),
N::NegInt(i) => visitor.visit_i64(i),
N::Float(f) => visitor.visit_f64(f),
}
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
bytes byte_buf option unit unit_struct newtype_struct seq tuple
tuple_struct map struct enum identifier ignored_any
}
}
impl<'de, 'a> Deserializer<'de> for &'a Number {
type Error = Error;
#[inline]
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
match self.n {
N::PosInt(i) => visitor.visit_u64(i),
N::NegInt(i) => visitor.visit_i64(i),
N::Float(f) => visitor.visit_f64(f),
}
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
bytes byte_buf option unit unit_struct newtype_struct seq tuple
tuple_struct map struct enum identifier ignored_any
}
}
macro_rules! from_signed {
($($signed_ty:ident)*) => {
$(
impl From<$signed_ty> for Number {
#[inline]
#[allow(clippy::cast_sign_loss)]
fn from(i: $signed_ty) -> Self {
if i < 0 {
Number { n: N::NegInt(i as i64) }
} else {
Number { n: N::PosInt(i as u64) }
}
}
}
)*
};
}
macro_rules! from_unsigned {
($($unsigned_ty:ident)*) => {
$(
impl From<$unsigned_ty> for Number {
#[inline]
fn from(u: $unsigned_ty) -> Self {
Number { n: N::PosInt(u as u64) }
}
}
)*
};
}
from_signed!(i8 i16 i32 i64 isize);
from_unsigned!(u8 u16 u32 u64 usize);
impl From<f32> for Number {
fn from(f: f32) -> Self {
Number::from(f as f64)
}
}
impl From<f64> for Number {
fn from(mut f: f64) -> Self {
if f.is_nan() {
// Destroy NaN sign, signaling, and payload. YAML only has one NaN.
f = f64::NAN.copysign(1.0);
}
Number { n: N::Float(f) }
}
}
// This is fine, because we don't _really_ implement hash for floats
// all other hash functions should work as expected
#[allow(clippy::derived_hash_with_manual_eq)]
impl Hash for Number {
fn hash<H: Hasher>(&self, state: &mut H) {
match self.n {
N::Float(_) => {
// you should feel bad for using f64 as a map key
3.hash(state);
}
N::PosInt(u) => u.hash(state),
N::NegInt(i) => i.hash(state),
}
}
}
pub(crate) fn unexpected(number: &Number) -> Unexpected {
match number.n {
N::PosInt(u) => Unexpected::Unsigned(u),
N::NegInt(i) => Unexpected::Signed(i),
N::Float(f) => Unexpected::Float(f),
}
}

34
vendor/serde_yaml/src/path.rs vendored Normal file
View File

@@ -0,0 +1,34 @@
use std::fmt::{self, Display};
/// Path to the current value in the input, like `dependencies.serde.typo1`.
#[derive(Copy, Clone)]
pub enum Path<'a> {
Root,
Seq { parent: &'a Path<'a>, index: usize },
Map { parent: &'a Path<'a>, key: &'a str },
Alias { parent: &'a Path<'a> },
Unknown { parent: &'a Path<'a> },
}
impl<'a> Display for Path<'a> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
struct Parent<'a>(&'a Path<'a>);
impl<'a> Display for Parent<'a> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match self.0 {
Path::Root => Ok(()),
path => write!(formatter, "{}.", path),
}
}
}
match self {
Path::Root => formatter.write_str("."),
Path::Seq { parent, index } => write!(formatter, "{}[{}]", parent, index),
Path::Map { parent, key } => write!(formatter, "{}{}", Parent(parent), key),
Path::Alias { parent } => write!(formatter, "{}", parent),
Path::Unknown { parent } => write!(formatter, "{}?", Parent(parent)),
}
}
}

714
vendor/serde_yaml/src/ser.rs vendored Normal file
View File

@@ -0,0 +1,714 @@
//! YAML Serialization
//!
//! This module provides YAML serialization with the type `Serializer`.
use crate::error::{self, Error, ErrorImpl};
use crate::libyaml;
use crate::libyaml::emitter::{Emitter, Event, Mapping, Scalar, ScalarStyle, Sequence};
use crate::value::tagged::{self, MaybeTag};
use serde::de::Visitor;
use serde::ser::{self, Serializer as _};
use std::fmt::{self, Display};
use std::io;
use std::marker::PhantomData;
use std::mem;
use std::num;
use std::str;
type Result<T, E = Error> = std::result::Result<T, E>;
/// A structure for serializing Rust values into YAML.
///
/// # Example
///
/// ```
/// use anyhow::Result;
/// use serde::Serialize;
/// use std::collections::BTreeMap;
///
/// fn main() -> Result<()> {
/// let mut buffer = Vec::new();
/// let mut ser = serde_yaml::Serializer::new(&mut buffer);
///
/// let mut object = BTreeMap::new();
/// object.insert("k", 107);
/// object.serialize(&mut ser)?;
///
/// object.insert("J", 74);
/// object.serialize(&mut ser)?;
///
/// assert_eq!(buffer, b"k: 107\n---\nJ: 74\nk: 107\n");
/// Ok(())
/// }
/// ```
pub struct Serializer<W> {
depth: usize,
state: State,
emitter: Emitter<'static>,
writer: PhantomData<W>,
}
enum State {
NothingInParticular,
CheckForTag,
CheckForDuplicateTag,
FoundTag(String),
AlreadyTagged,
}
impl<W> Serializer<W>
where
W: io::Write,
{
/// Creates a new YAML serializer.
pub fn new(writer: W) -> Self {
let mut emitter = Emitter::new({
let writer = Box::new(writer);
unsafe { mem::transmute::<Box<dyn io::Write>, Box<dyn io::Write>>(writer) }
});
emitter.emit(Event::StreamStart).unwrap();
Serializer {
depth: 0,
state: State::NothingInParticular,
emitter,
writer: PhantomData,
}
}
/// Calls [`.flush()`](io::Write::flush) on the underlying `io::Write`
/// object.
pub fn flush(&mut self) -> Result<()> {
self.emitter.flush()?;
Ok(())
}
/// Unwrap the underlying `io::Write` object from the `Serializer`.
pub fn into_inner(mut self) -> Result<W> {
self.emitter.emit(Event::StreamEnd)?;
self.emitter.flush()?;
let writer = self.emitter.into_inner();
Ok(*unsafe { Box::from_raw(Box::into_raw(writer).cast::<W>()) })
}
fn emit_scalar(&mut self, mut scalar: Scalar) -> Result<()> {
self.flush_mapping_start()?;
if let Some(tag) = self.take_tag() {
scalar.tag = Some(tag);
}
self.value_start()?;
self.emitter.emit(Event::Scalar(scalar))?;
self.value_end()
}
fn emit_sequence_start(&mut self) -> Result<()> {
self.flush_mapping_start()?;
self.value_start()?;
let tag = self.take_tag();
self.emitter.emit(Event::SequenceStart(Sequence { tag }))?;
Ok(())
}
fn emit_sequence_end(&mut self) -> Result<()> {
self.emitter.emit(Event::SequenceEnd)?;
self.value_end()
}
fn emit_mapping_start(&mut self) -> Result<()> {
self.flush_mapping_start()?;
self.value_start()?;
let tag = self.take_tag();
self.emitter.emit(Event::MappingStart(Mapping { tag }))?;
Ok(())
}
fn emit_mapping_end(&mut self) -> Result<()> {
self.emitter.emit(Event::MappingEnd)?;
self.value_end()
}
fn value_start(&mut self) -> Result<()> {
if self.depth == 0 {
self.emitter.emit(Event::DocumentStart)?;
}
self.depth += 1;
Ok(())
}
fn value_end(&mut self) -> Result<()> {
self.depth -= 1;
if self.depth == 0 {
self.emitter.emit(Event::DocumentEnd)?;
}
Ok(())
}
fn take_tag(&mut self) -> Option<String> {
let state = mem::replace(&mut self.state, State::NothingInParticular);
if let State::FoundTag(mut tag) = state {
if !tag.starts_with('!') {
tag.insert(0, '!');
}
Some(tag)
} else {
self.state = state;
None
}
}
fn flush_mapping_start(&mut self) -> Result<()> {
if let State::CheckForTag = self.state {
self.state = State::NothingInParticular;
self.emit_mapping_start()?;
} else if let State::CheckForDuplicateTag = self.state {
self.state = State::NothingInParticular;
}
Ok(())
}
}
impl<'a, W> ser::Serializer for &'a mut Serializer<W>
where
W: io::Write,
{
type Ok = ();
type Error = Error;
type SerializeSeq = Self;
type SerializeTuple = Self;
type SerializeTupleStruct = Self;
type SerializeTupleVariant = Self;
type SerializeMap = Self;
type SerializeStruct = Self;
type SerializeStructVariant = Self;
fn serialize_bool(self, v: bool) -> Result<()> {
self.emit_scalar(Scalar {
tag: None,
value: if v { "true" } else { "false" },
style: ScalarStyle::Plain,
})
}
fn serialize_i8(self, v: i8) -> Result<()> {
self.emit_scalar(Scalar {
tag: None,
value: itoa::Buffer::new().format(v),
style: ScalarStyle::Plain,
})
}
fn serialize_i16(self, v: i16) -> Result<()> {
self.emit_scalar(Scalar {
tag: None,
value: itoa::Buffer::new().format(v),
style: ScalarStyle::Plain,
})
}
fn serialize_i32(self, v: i32) -> Result<()> {
self.emit_scalar(Scalar {
tag: None,
value: itoa::Buffer::new().format(v),
style: ScalarStyle::Plain,
})
}
fn serialize_i64(self, v: i64) -> Result<()> {
self.emit_scalar(Scalar {
tag: None,
value: itoa::Buffer::new().format(v),
style: ScalarStyle::Plain,
})
}
fn serialize_i128(self, v: i128) -> Result<()> {
self.emit_scalar(Scalar {
tag: None,
value: itoa::Buffer::new().format(v),
style: ScalarStyle::Plain,
})
}
fn serialize_u8(self, v: u8) -> Result<()> {
self.emit_scalar(Scalar {
tag: None,
value: itoa::Buffer::new().format(v),
style: ScalarStyle::Plain,
})
}
fn serialize_u16(self, v: u16) -> Result<()> {
self.emit_scalar(Scalar {
tag: None,
value: itoa::Buffer::new().format(v),
style: ScalarStyle::Plain,
})
}
fn serialize_u32(self, v: u32) -> Result<()> {
self.emit_scalar(Scalar {
tag: None,
value: itoa::Buffer::new().format(v),
style: ScalarStyle::Plain,
})
}
fn serialize_u64(self, v: u64) -> Result<()> {
self.emit_scalar(Scalar {
tag: None,
value: itoa::Buffer::new().format(v),
style: ScalarStyle::Plain,
})
}
fn serialize_u128(self, v: u128) -> Result<()> {
self.emit_scalar(Scalar {
tag: None,
value: itoa::Buffer::new().format(v),
style: ScalarStyle::Plain,
})
}
fn serialize_f32(self, v: f32) -> Result<()> {
let mut buffer = ryu::Buffer::new();
self.emit_scalar(Scalar {
tag: None,
value: match v.classify() {
num::FpCategory::Infinite if v.is_sign_positive() => ".inf",
num::FpCategory::Infinite => "-.inf",
num::FpCategory::Nan => ".nan",
_ => buffer.format_finite(v),
},
style: ScalarStyle::Plain,
})
}
fn serialize_f64(self, v: f64) -> Result<()> {
let mut buffer = ryu::Buffer::new();
self.emit_scalar(Scalar {
tag: None,
value: match v.classify() {
num::FpCategory::Infinite if v.is_sign_positive() => ".inf",
num::FpCategory::Infinite => "-.inf",
num::FpCategory::Nan => ".nan",
_ => buffer.format_finite(v),
},
style: ScalarStyle::Plain,
})
}
fn serialize_char(self, value: char) -> Result<()> {
self.emit_scalar(Scalar {
tag: None,
value: value.encode_utf8(&mut [0u8; 4]),
style: ScalarStyle::SingleQuoted,
})
}
fn serialize_str(self, value: &str) -> Result<()> {
struct InferScalarStyle;
impl<'de> Visitor<'de> for InferScalarStyle {
type Value = ScalarStyle;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("I wonder")
}
fn visit_bool<E>(self, _v: bool) -> Result<Self::Value, E> {
Ok(ScalarStyle::SingleQuoted)
}
fn visit_i64<E>(self, _v: i64) -> Result<Self::Value, E> {
Ok(ScalarStyle::SingleQuoted)
}
fn visit_i128<E>(self, _v: i128) -> Result<Self::Value, E> {
Ok(ScalarStyle::SingleQuoted)
}
fn visit_u64<E>(self, _v: u64) -> Result<Self::Value, E> {
Ok(ScalarStyle::SingleQuoted)
}
fn visit_u128<E>(self, _v: u128) -> Result<Self::Value, E> {
Ok(ScalarStyle::SingleQuoted)
}
fn visit_f64<E>(self, _v: f64) -> Result<Self::Value, E> {
Ok(ScalarStyle::SingleQuoted)
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> {
Ok(if crate::de::digits_but_not_number(v) {
ScalarStyle::SingleQuoted
} else {
ScalarStyle::Any
})
}
fn visit_unit<E>(self) -> Result<Self::Value, E> {
Ok(ScalarStyle::SingleQuoted)
}
}
let style = if value.contains('\n') {
ScalarStyle::Literal
} else {
let result = crate::de::visit_untagged_scalar(
InferScalarStyle,
value,
None,
libyaml::parser::ScalarStyle::Plain,
);
result.unwrap_or(ScalarStyle::Any)
};
self.emit_scalar(Scalar {
tag: None,
value,
style,
})
}
fn serialize_bytes(self, _value: &[u8]) -> Result<()> {
Err(error::new(ErrorImpl::BytesUnsupported))
}
fn serialize_unit(self) -> Result<()> {
self.emit_scalar(Scalar {
tag: None,
value: "null",
style: ScalarStyle::Plain,
})
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
self.serialize_unit()
}
fn serialize_unit_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<()> {
self.serialize_str(variant)
}
fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
value.serialize(self)
}
fn serialize_newtype_variant<T>(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
if let State::FoundTag(_) = self.state {
return Err(error::new(ErrorImpl::SerializeNestedEnum));
}
self.state = State::FoundTag(variant.to_owned());
value.serialize(&mut *self)
}
fn serialize_none(self) -> Result<()> {
self.serialize_unit()
}
fn serialize_some<V>(self, value: &V) -> Result<()>
where
V: ?Sized + ser::Serialize,
{
value.serialize(self)
}
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
self.emit_sequence_start()?;
Ok(self)
}
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
self.emit_sequence_start()?;
Ok(self)
}
fn serialize_tuple_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleStruct> {
self.emit_sequence_start()?;
Ok(self)
}
fn serialize_tuple_variant(
self,
_enm: &'static str,
_idx: u32,
variant: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleVariant> {
if let State::FoundTag(_) = self.state {
return Err(error::new(ErrorImpl::SerializeNestedEnum));
}
self.state = State::FoundTag(variant.to_owned());
self.emit_sequence_start()?;
Ok(self)
}
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
if len == Some(1) {
self.state = if let State::FoundTag(_) = self.state {
self.emit_mapping_start()?;
State::CheckForDuplicateTag
} else {
State::CheckForTag
};
} else {
self.emit_mapping_start()?;
}
Ok(self)
}
fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
self.emit_mapping_start()?;
Ok(self)
}
fn serialize_struct_variant(
self,
_enm: &'static str,
_idx: u32,
variant: &'static str,
_len: usize,
) -> Result<Self::SerializeStructVariant> {
if let State::FoundTag(_) = self.state {
return Err(error::new(ErrorImpl::SerializeNestedEnum));
}
self.state = State::FoundTag(variant.to_owned());
self.emit_mapping_start()?;
Ok(self)
}
fn collect_str<T>(self, value: &T) -> Result<Self::Ok>
where
T: ?Sized + Display,
{
let string = if let State::CheckForTag | State::CheckForDuplicateTag = self.state {
match tagged::check_for_tag(value) {
MaybeTag::NotTag(string) => string,
MaybeTag::Tag(string) => {
return if let State::CheckForDuplicateTag = self.state {
Err(error::new(ErrorImpl::SerializeNestedEnum))
} else {
self.state = State::FoundTag(string);
Ok(())
};
}
}
} else {
value.to_string()
};
self.serialize_str(&string)
}
}
impl<'a, W> ser::SerializeSeq for &'a mut Serializer<W>
where
W: io::Write,
{
type Ok = ();
type Error = Error;
fn serialize_element<T>(&mut self, elem: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
elem.serialize(&mut **self)
}
fn end(self) -> Result<()> {
self.emit_sequence_end()
}
}
impl<'a, W> ser::SerializeTuple for &'a mut Serializer<W>
where
W: io::Write,
{
type Ok = ();
type Error = Error;
fn serialize_element<T>(&mut self, elem: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
elem.serialize(&mut **self)
}
fn end(self) -> Result<()> {
self.emit_sequence_end()
}
}
impl<'a, W> ser::SerializeTupleStruct for &'a mut Serializer<W>
where
W: io::Write,
{
type Ok = ();
type Error = Error;
fn serialize_field<V>(&mut self, value: &V) -> Result<()>
where
V: ?Sized + ser::Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<()> {
self.emit_sequence_end()
}
}
impl<'a, W> ser::SerializeTupleVariant for &'a mut Serializer<W>
where
W: io::Write,
{
type Ok = ();
type Error = Error;
fn serialize_field<V>(&mut self, v: &V) -> Result<()>
where
V: ?Sized + ser::Serialize,
{
v.serialize(&mut **self)
}
fn end(self) -> Result<()> {
self.emit_sequence_end()
}
}
impl<'a, W> ser::SerializeMap for &'a mut Serializer<W>
where
W: io::Write,
{
type Ok = ();
type Error = Error;
fn serialize_key<T>(&mut self, key: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
self.flush_mapping_start()?;
key.serialize(&mut **self)
}
fn serialize_value<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
value.serialize(&mut **self)
}
fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<(), Self::Error>
where
K: ?Sized + ser::Serialize,
V: ?Sized + ser::Serialize,
{
key.serialize(&mut **self)?;
let tagged = matches!(self.state, State::FoundTag(_));
value.serialize(&mut **self)?;
if tagged {
self.state = State::AlreadyTagged;
}
Ok(())
}
fn end(self) -> Result<()> {
if let State::CheckForTag = self.state {
self.emit_mapping_start()?;
}
if !matches!(self.state, State::AlreadyTagged) {
self.emit_mapping_end()?;
}
self.state = State::NothingInParticular;
Ok(())
}
}
impl<'a, W> ser::SerializeStruct for &'a mut Serializer<W>
where
W: io::Write,
{
type Ok = ();
type Error = Error;
fn serialize_field<V>(&mut self, key: &'static str, value: &V) -> Result<()>
where
V: ?Sized + ser::Serialize,
{
self.serialize_str(key)?;
value.serialize(&mut **self)
}
fn end(self) -> Result<()> {
self.emit_mapping_end()
}
}
impl<'a, W> ser::SerializeStructVariant for &'a mut Serializer<W>
where
W: io::Write,
{
type Ok = ();
type Error = Error;
fn serialize_field<V>(&mut self, field: &'static str, v: &V) -> Result<()>
where
V: ?Sized + ser::Serialize,
{
self.serialize_str(field)?;
v.serialize(&mut **self)
}
fn end(self) -> Result<()> {
self.emit_mapping_end()
}
}
/// Serialize the given data structure as YAML into the IO stream.
///
/// Serialization can fail if `T`'s implementation of `Serialize` decides to
/// return an error.
pub fn to_writer<W, T>(writer: W, value: &T) -> Result<()>
where
W: io::Write,
T: ?Sized + ser::Serialize,
{
let mut serializer = Serializer::new(writer);
value.serialize(&mut serializer)
}
/// Serialize the given data structure as a String of YAML.
///
/// Serialization can fail if `T`'s implementation of `Serialize` decides to
/// return an error.
pub fn to_string<T>(value: &T) -> Result<String>
where
T: ?Sized + ser::Serialize,
{
let mut vec = Vec::with_capacity(128);
to_writer(&mut vec, value)?;
String::from_utf8(vec).map_err(|error| error::new(ErrorImpl::FromUtf8(error)))
}

1242
vendor/serde_yaml/src/value/de.rs vendored Normal file

File diff suppressed because it is too large Load Diff

57
vendor/serde_yaml/src/value/debug.rs vendored Normal file
View File

@@ -0,0 +1,57 @@
use crate::mapping::Mapping;
use crate::value::{Number, Value};
use std::fmt::{self, Debug, Display};
impl Debug for Value {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
match self {
Value::Null => formatter.write_str("Null"),
Value::Bool(boolean) => write!(formatter, "Bool({})", boolean),
Value::Number(number) => write!(formatter, "Number({})", number),
Value::String(string) => write!(formatter, "String({:?})", string),
Value::Sequence(sequence) => {
formatter.write_str("Sequence ")?;
formatter.debug_list().entries(sequence).finish()
}
Value::Mapping(mapping) => Debug::fmt(mapping, formatter),
Value::Tagged(tagged) => Debug::fmt(tagged, formatter),
}
}
}
struct DisplayNumber<'a>(&'a Number);
impl<'a> Debug for DisplayNumber<'a> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(self.0, formatter)
}
}
impl Debug for Number {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "Number({})", self)
}
}
impl Debug for Mapping {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("Mapping ")?;
let mut debug = formatter.debug_map();
for (k, v) in self {
let tmp;
debug.entry(
match k {
Value::Bool(boolean) => boolean,
Value::Number(number) => {
tmp = DisplayNumber(number);
&tmp
}
Value::String(string) => string,
_ => k,
},
v,
);
}
debug.finish()
}
}

178
vendor/serde_yaml/src/value/from.rs vendored Normal file
View File

@@ -0,0 +1,178 @@
use crate::{Mapping, Value};
// Implement a bunch of conversion to make it easier to create YAML values
// on the fly.
macro_rules! from_number {
($($ty:ident)*) => {
$(
impl From<$ty> for Value {
fn from(n: $ty) -> Self {
Value::Number(n.into())
}
}
)*
};
}
from_number! {
i8 i16 i32 i64 isize
u8 u16 u32 u64 usize
f32 f64
}
impl From<bool> for Value {
/// Convert boolean to `Value`
///
/// # Examples
///
/// ```
/// use serde_yaml::Value;
///
/// let b = false;
/// let x: Value = b.into();
/// ```
fn from(f: bool) -> Self {
Value::Bool(f)
}
}
impl From<String> for Value {
/// Convert `String` to `Value`
///
/// # Examples
///
/// ```
/// use serde_yaml::Value;
///
/// let s: String = "lorem".to_string();
/// let x: Value = s.into();
/// ```
fn from(f: String) -> Self {
Value::String(f)
}
}
impl<'a> From<&'a str> for Value {
/// Convert string slice to `Value`
///
/// # Examples
///
/// ```
/// use serde_yaml::Value;
///
/// let s: &str = "lorem";
/// let x: Value = s.into();
/// ```
fn from(f: &str) -> Self {
Value::String(f.to_string())
}
}
use std::borrow::Cow;
impl<'a> From<Cow<'a, str>> for Value {
/// Convert copy-on-write string to `Value`
///
/// # Examples
///
/// ```
/// use serde_yaml::Value;
/// use std::borrow::Cow;
///
/// let s: Cow<str> = Cow::Borrowed("lorem");
/// let x: Value = s.into();
/// ```
///
/// ```
/// use serde_yaml::Value;
/// use std::borrow::Cow;
///
/// let s: Cow<str> = Cow::Owned("lorem".to_string());
/// let x: Value = s.into();
/// ```
fn from(f: Cow<'a, str>) -> Self {
Value::String(f.to_string())
}
}
impl From<Mapping> for Value {
/// Convert map (with string keys) to `Value`
///
/// # Examples
///
/// ```
/// use serde_yaml::{Mapping, Value};
///
/// let mut m = Mapping::new();
/// m.insert("Lorem".into(), "ipsum".into());
/// let x: Value = m.into();
/// ```
fn from(f: Mapping) -> Self {
Value::Mapping(f)
}
}
impl<T: Into<Value>> From<Vec<T>> for Value {
/// Convert a `Vec` to `Value`
///
/// # Examples
///
/// ```
/// use serde_yaml::Value;
///
/// let v = vec!["lorem", "ipsum", "dolor"];
/// let x: Value = v.into();
/// ```
fn from(f: Vec<T>) -> Self {
Value::Sequence(f.into_iter().map(Into::into).collect())
}
}
impl<'a, T: Clone + Into<Value>> From<&'a [T]> for Value {
/// Convert a slice to `Value`
///
/// # Examples
///
/// ```
/// use serde_yaml::Value;
///
/// let v: &[&str] = &["lorem", "ipsum", "dolor"];
/// let x: Value = v.into();
/// ```
fn from(f: &'a [T]) -> Self {
Value::Sequence(f.iter().cloned().map(Into::into).collect())
}
}
impl<T: Into<Value>> FromIterator<T> for Value {
/// Convert an iteratable type to a YAML sequence
///
/// # Examples
///
/// ```
/// use serde_yaml::Value;
///
/// let v = std::iter::repeat(42).take(5);
/// let x: Value = v.collect();
/// ```
///
/// ```
/// use serde_yaml::Value;
///
/// let v: Vec<_> = vec!["lorem", "ipsum", "dolor"];
/// let x: Value = v.into_iter().collect();
/// ```
///
/// ```
/// use std::iter::FromIterator;
/// use serde_yaml::Value;
///
/// let x: Value = Value::from_iter(vec!["lorem", "ipsum", "dolor"]);
/// ```
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let vec = iter.into_iter().map(T::into).collect();
Value::Sequence(vec)
}
}

279
vendor/serde_yaml/src/value/index.rs vendored Normal file
View File

@@ -0,0 +1,279 @@
use crate::mapping::Entry;
use crate::{mapping, private, Mapping, Value};
use std::fmt::{self, Debug};
use std::ops;
/// A type that can be used to index into a `serde_yaml::Value`. See the `get`
/// and `get_mut` methods of `Value`.
///
/// This trait is sealed and cannot be implemented for types outside of
/// `serde_yaml`.
pub trait Index: private::Sealed {
/// Return None if the key is not already in the sequence or object.
#[doc(hidden)]
fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value>;
/// Return None if the key is not already in the sequence or object.
#[doc(hidden)]
fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value>;
/// Panic if sequence index out of bounds. If key is not already in the object,
/// insert it with a value of null. Panic if Value is a type that cannot be
/// indexed into, except if Value is null then it can be treated as an empty
/// object.
#[doc(hidden)]
fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value;
}
impl Index for usize {
fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
match v.untag_ref() {
Value::Sequence(vec) => vec.get(*self),
Value::Mapping(vec) => vec.get(&Value::Number((*self).into())),
_ => None,
}
}
fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
match v.untag_mut() {
Value::Sequence(vec) => vec.get_mut(*self),
Value::Mapping(vec) => vec.get_mut(&Value::Number((*self).into())),
_ => None,
}
}
fn index_or_insert<'v>(&self, mut v: &'v mut Value) -> &'v mut Value {
loop {
match v {
Value::Sequence(vec) => {
let len = vec.len();
return vec.get_mut(*self).unwrap_or_else(|| {
panic!(
"cannot access index {} of YAML sequence of length {}",
self, len
)
});
}
Value::Mapping(map) => {
let n = Value::Number((*self).into());
return map.entry(n).or_insert(Value::Null);
}
Value::Tagged(tagged) => v = &mut tagged.value,
_ => panic!("cannot access index {} of YAML {}", self, Type(v)),
}
}
}
}
fn index_into_mapping<'v, I>(index: &I, v: &'v Value) -> Option<&'v Value>
where
I: ?Sized + mapping::Index,
{
match v.untag_ref() {
Value::Mapping(map) => map.get(index),
_ => None,
}
}
fn index_into_mut_mapping<'v, I>(index: &I, v: &'v mut Value) -> Option<&'v mut Value>
where
I: ?Sized + mapping::Index,
{
match v.untag_mut() {
Value::Mapping(map) => map.get_mut(index),
_ => None,
}
}
fn index_or_insert_mapping<'v, I>(index: &I, mut v: &'v mut Value) -> &'v mut Value
where
I: ?Sized + mapping::Index + ToOwned + Debug,
Value: From<I::Owned>,
{
if let Value::Null = *v {
*v = Value::Mapping(Mapping::new());
return match v {
Value::Mapping(map) => match map.entry(index.to_owned().into()) {
Entry::Vacant(entry) => entry.insert(Value::Null),
Entry::Occupied(_) => unreachable!(),
},
_ => unreachable!(),
};
}
loop {
match v {
Value::Mapping(map) => {
return map.entry(index.to_owned().into()).or_insert(Value::Null);
}
Value::Tagged(tagged) => v = &mut tagged.value,
_ => panic!("cannot access key {:?} in YAML {}", index, Type(v)),
}
}
}
impl Index for Value {
fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
index_into_mapping(self, v)
}
fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
index_into_mut_mapping(self, v)
}
fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
index_or_insert_mapping(self, v)
}
}
impl Index for str {
fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
index_into_mapping(self, v)
}
fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
index_into_mut_mapping(self, v)
}
fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
index_or_insert_mapping(self, v)
}
}
impl Index for String {
fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
self.as_str().index_into(v)
}
fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
self.as_str().index_into_mut(v)
}
fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
self.as_str().index_or_insert(v)
}
}
impl<'a, T> Index for &'a T
where
T: ?Sized + Index,
{
fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
(**self).index_into(v)
}
fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
(**self).index_into_mut(v)
}
fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
(**self).index_or_insert(v)
}
}
/// Used in panic messages.
struct Type<'a>(&'a Value);
impl<'a> fmt::Display for Type<'a> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
match self.0 {
Value::Null => formatter.write_str("null"),
Value::Bool(_) => formatter.write_str("boolean"),
Value::Number(_) => formatter.write_str("number"),
Value::String(_) => formatter.write_str("string"),
Value::Sequence(_) => formatter.write_str("sequence"),
Value::Mapping(_) => formatter.write_str("mapping"),
Value::Tagged(_) => unreachable!(),
}
}
}
// The usual semantics of Index is to panic on invalid indexing.
//
// That said, the usual semantics are for things like `Vec` and `BTreeMap` which
// have different use cases than Value. If you are working with a Vec, you know
// that you are working with a Vec and you can get the len of the Vec and make
// sure your indices are within bounds. The Value use cases are more
// loosey-goosey. You got some YAML from an endpoint and you want to pull values
// out of it. Outside of this Index impl, you already have the option of using
// `value.as_sequence()` and working with the Vec directly, or matching on
// `Value::Sequence` and getting the Vec directly. The Index impl means you can
// skip that and index directly into the thing using a concise syntax. You don't
// have to check the type, you don't have to check the len, it is all about what
// you expect the Value to look like.
//
// Basically the use cases that would be well served by panicking here are
// better served by using one of the other approaches: `get` and `get_mut`,
// `as_sequence`, or match. The value of this impl is that it adds a way of
// working with Value that is not well served by the existing approaches:
// concise and careless and sometimes that is exactly what you want.
impl<I> ops::Index<I> for Value
where
I: Index,
{
type Output = Value;
/// Index into a `serde_yaml::Value` using the syntax `value[0]` or
/// `value["k"]`.
///
/// Returns `Value::Null` if the type of `self` does not match the type of
/// the index, for example if the index is a string and `self` is a sequence
/// or a number. Also returns `Value::Null` if the given key does not exist
/// in the map or the given index is not within the bounds of the sequence.
///
/// For retrieving deeply nested values, you should have a look at the
/// `Value::pointer` method.
///
/// # Examples
///
/// ```
/// # use serde_yaml::Value;
/// #
/// # fn main() -> serde_yaml::Result<()> {
/// let data: serde_yaml::Value = serde_yaml::from_str(r#"{ x: { y: [z, zz] } }"#)?;
///
/// assert_eq!(data["x"]["y"], serde_yaml::from_str::<Value>(r#"["z", "zz"]"#).unwrap());
/// assert_eq!(data["x"]["y"][0], serde_yaml::from_str::<Value>(r#""z""#).unwrap());
///
/// assert_eq!(data["a"], serde_yaml::from_str::<Value>(r#"null"#).unwrap()); // returns null for undefined values
/// assert_eq!(data["a"]["b"], serde_yaml::from_str::<Value>(r#"null"#).unwrap()); // does not panic
/// # Ok(())
/// # }
/// ```
fn index(&self, index: I) -> &Value {
static NULL: Value = Value::Null;
index.index_into(self).unwrap_or(&NULL)
}
}
impl<I> ops::IndexMut<I> for Value
where
I: Index,
{
/// Write into a `serde_yaml::Value` using the syntax `value[0] = ...` or
/// `value["k"] = ...`.
///
/// If the index is a number, the value must be a sequence of length bigger
/// than the index. Indexing into a value that is not a sequence or a
/// sequence that is too small will panic.
///
/// If the index is a string, the value must be an object or null which is
/// treated like an empty object. If the key is not already present in the
/// object, it will be inserted with a value of null. Indexing into a value
/// that is neither an object nor null will panic.
///
/// # Examples
///
/// ```
/// # fn main() -> serde_yaml::Result<()> {
/// let mut data: serde_yaml::Value = serde_yaml::from_str(r#"{x: 0}"#)?;
///
/// // replace an existing key
/// data["x"] = serde_yaml::from_str(r#"1"#)?;
///
/// // insert a new key
/// data["y"] = serde_yaml::from_str(r#"[false, false, false]"#)?;
///
/// // replace a value in a sequence
/// data["y"][0] = serde_yaml::from_str(r#"true"#)?;
///
/// // inserted a deeply nested key
/// data["a"]["b"]["c"]["d"] = serde_yaml::from_str(r#"true"#)?;
///
/// println!("{:?}", data);
/// # Ok(())
/// # }
/// ```
fn index_mut(&mut self, index: I) -> &mut Value {
index.index_or_insert(self)
}
}

698
vendor/serde_yaml/src/value/mod.rs vendored Normal file
View File

@@ -0,0 +1,698 @@
//! The Value enum, a loosely typed way of representing any valid YAML value.
mod de;
mod debug;
mod from;
mod index;
mod partial_eq;
mod ser;
pub(crate) mod tagged;
use crate::error::{self, Error, ErrorImpl};
use serde::de::{Deserialize, DeserializeOwned, IntoDeserializer};
use serde::Serialize;
use std::hash::{Hash, Hasher};
use std::mem;
pub use self::index::Index;
pub use self::ser::Serializer;
pub use self::tagged::{Tag, TaggedValue};
#[doc(inline)]
pub use crate::mapping::Mapping;
pub use crate::number::Number;
/// Represents any valid YAML value.
#[derive(Clone, PartialEq, PartialOrd)]
pub enum Value {
/// Represents a YAML null value.
Null,
/// Represents a YAML boolean.
Bool(bool),
/// Represents a YAML numerical value, whether integer or floating point.
Number(Number),
/// Represents a YAML string.
String(String),
/// Represents a YAML sequence in which the elements are
/// `serde_yaml::Value`.
Sequence(Sequence),
/// Represents a YAML mapping in which the keys and values are both
/// `serde_yaml::Value`.
Mapping(Mapping),
/// A representation of YAML's `!Tag` syntax, used for enums.
Tagged(Box<TaggedValue>),
}
/// The default value is `Value::Null`.
///
/// This is useful for handling omitted `Value` fields when deserializing.
///
/// # Examples
///
/// ```
/// # use serde_derive::Deserialize;
/// use serde::Deserialize;
/// use serde_yaml::Value;
///
/// #[derive(Deserialize)]
/// struct Settings {
/// level: i32,
/// #[serde(default)]
/// extras: Value,
/// }
///
/// # fn try_main() -> Result<(), serde_yaml::Error> {
/// let data = r#" { "level": 42 } "#;
/// let s: Settings = serde_yaml::from_str(data)?;
///
/// assert_eq!(s.level, 42);
/// assert_eq!(s.extras, Value::Null);
/// #
/// # Ok(())
/// # }
/// #
/// # try_main().unwrap()
/// ```
impl Default for Value {
fn default() -> Value {
Value::Null
}
}
/// A YAML sequence in which the elements are `serde_yaml::Value`.
pub type Sequence = Vec<Value>;
/// Convert a `T` into `serde_yaml::Value` which is an enum that can represent
/// any valid YAML data.
///
/// This conversion can fail if `T`'s implementation of `Serialize` decides to
/// return an error.
///
/// ```
/// # use serde_yaml::Value;
/// let val = serde_yaml::to_value("s").unwrap();
/// assert_eq!(val, Value::String("s".to_owned()));
/// ```
pub fn to_value<T>(value: T) -> Result<Value, Error>
where
T: Serialize,
{
value.serialize(Serializer)
}
/// Interpret a `serde_yaml::Value` as an instance of type `T`.
///
/// This conversion can fail if the structure of the Value does not match the
/// structure expected by `T`, for example if `T` is a struct type but the Value
/// contains something other than a YAML map. It can also fail if the structure
/// is correct but `T`'s implementation of `Deserialize` decides that something
/// is wrong with the data, for example required struct fields are missing from
/// the YAML map or some number is too big to fit in the expected primitive
/// type.
///
/// ```
/// # use serde_yaml::Value;
/// let val = Value::String("foo".to_owned());
/// let s: String = serde_yaml::from_value(val).unwrap();
/// assert_eq!("foo", s);
/// ```
pub fn from_value<T>(value: Value) -> Result<T, Error>
where
T: DeserializeOwned,
{
Deserialize::deserialize(value)
}
impl Value {
/// Index into a YAML sequence or map. A string index can be used to access
/// a value in a map, and a usize index can be used to access an element of
/// an sequence.
///
/// Returns `None` if the type of `self` does not match the type of the
/// index, for example if the index is a string and `self` is a sequence or
/// a number. Also returns `None` if the given key does not exist in the map
/// or the given index is not within the bounds of the sequence.
///
/// ```
/// # fn main() -> serde_yaml::Result<()> {
/// use serde_yaml::Value;
///
/// let object: Value = serde_yaml::from_str(r#"{ A: 65, B: 66, C: 67 }"#)?;
/// let x = object.get("A").unwrap();
/// assert_eq!(x, 65);
///
/// let sequence: Value = serde_yaml::from_str(r#"[ "A", "B", "C" ]"#)?;
/// let x = sequence.get(2).unwrap();
/// assert_eq!(x, &Value::String("C".into()));
///
/// assert_eq!(sequence.get("A"), None);
/// # Ok(())
/// # }
/// ```
///
/// Square brackets can also be used to index into a value in a more concise
/// way. This returns `Value::Null` in cases where `get` would have returned
/// `None`.
///
/// ```
/// # use serde_yaml::Value;
/// #
/// # fn main() -> serde_yaml::Result<()> {
/// let object: Value = serde_yaml::from_str(r#"
/// A: [a, á, à]
/// B: [b, b́]
/// C: [c, ć, ć̣, ḉ]
/// 42: true
/// "#)?;
/// assert_eq!(object["B"][0], Value::String("b".into()));
///
/// assert_eq!(object[Value::String("D".into())], Value::Null);
/// assert_eq!(object["D"], Value::Null);
/// assert_eq!(object[0]["x"]["y"]["z"], Value::Null);
///
/// assert_eq!(object[42], Value::Bool(true));
/// # Ok(())
/// # }
/// ```
pub fn get<I: Index>(&self, index: I) -> Option<&Value> {
index.index_into(self)
}
/// Index into a YAML sequence or map. A string index can be used to access
/// a value in a map, and a usize index can be used to access an element of
/// an sequence.
///
/// Returns `None` if the type of `self` does not match the type of the
/// index, for example if the index is a string and `self` is a sequence or
/// a number. Also returns `None` if the given key does not exist in the map
/// or the given index is not within the bounds of the sequence.
pub fn get_mut<I: Index>(&mut self, index: I) -> Option<&mut Value> {
index.index_into_mut(self)
}
/// Returns true if the `Value` is a Null. Returns false otherwise.
///
/// For any Value on which `is_null` returns true, `as_null` is guaranteed
/// to return `Some(())`.
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("null").unwrap();
/// assert!(v.is_null());
/// ```
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("false").unwrap();
/// assert!(!v.is_null());
/// ```
pub fn is_null(&self) -> bool {
if let Value::Null = self.untag_ref() {
true
} else {
false
}
}
/// If the `Value` is a Null, returns (). Returns None otherwise.
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("null").unwrap();
/// assert_eq!(v.as_null(), Some(()));
/// ```
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("false").unwrap();
/// assert_eq!(v.as_null(), None);
/// ```
pub fn as_null(&self) -> Option<()> {
match self.untag_ref() {
Value::Null => Some(()),
_ => None,
}
}
/// Returns true if the `Value` is a Boolean. Returns false otherwise.
///
/// For any Value on which `is_boolean` returns true, `as_bool` is
/// guaranteed to return the boolean value.
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("true").unwrap();
/// assert!(v.is_bool());
/// ```
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("42").unwrap();
/// assert!(!v.is_bool());
/// ```
pub fn is_bool(&self) -> bool {
self.as_bool().is_some()
}
/// If the `Value` is a Boolean, returns the associated bool. Returns None
/// otherwise.
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("true").unwrap();
/// assert_eq!(v.as_bool(), Some(true));
/// ```
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("42").unwrap();
/// assert_eq!(v.as_bool(), None);
/// ```
pub fn as_bool(&self) -> Option<bool> {
match self.untag_ref() {
Value::Bool(b) => Some(*b),
_ => None,
}
}
/// Returns true if the `Value` is a Number. Returns false otherwise.
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("5").unwrap();
/// assert!(v.is_number());
/// ```
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("true").unwrap();
/// assert!(!v.is_number());
/// ```
pub fn is_number(&self) -> bool {
match self.untag_ref() {
Value::Number(_) => true,
_ => false,
}
}
/// Returns true if the `Value` is an integer between `i64::MIN` and
/// `i64::MAX`.
///
/// For any Value on which `is_i64` returns true, `as_i64` is guaranteed to
/// return the integer value.
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("1337").unwrap();
/// assert!(v.is_i64());
/// ```
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("null").unwrap();
/// assert!(!v.is_i64());
/// ```
pub fn is_i64(&self) -> bool {
self.as_i64().is_some()
}
/// If the `Value` is an integer, represent it as i64 if possible. Returns
/// None otherwise.
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("1337").unwrap();
/// assert_eq!(v.as_i64(), Some(1337));
/// ```
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("false").unwrap();
/// assert_eq!(v.as_i64(), None);
/// ```
pub fn as_i64(&self) -> Option<i64> {
match self.untag_ref() {
Value::Number(n) => n.as_i64(),
_ => None,
}
}
/// Returns true if the `Value` is an integer between `u64::MIN` and
/// `u64::MAX`.
///
/// For any Value on which `is_u64` returns true, `as_u64` is guaranteed to
/// return the integer value.
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("1337").unwrap();
/// assert!(v.is_u64());
/// ```
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("null").unwrap();
/// assert!(!v.is_u64());
/// ```
pub fn is_u64(&self) -> bool {
self.as_u64().is_some()
}
/// If the `Value` is an integer, represent it as u64 if possible. Returns
/// None otherwise.
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("1337").unwrap();
/// assert_eq!(v.as_u64(), Some(1337));
/// ```
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("false").unwrap();
/// assert_eq!(v.as_u64(), None);
/// ```
pub fn as_u64(&self) -> Option<u64> {
match self.untag_ref() {
Value::Number(n) => n.as_u64(),
_ => None,
}
}
/// Returns true if the `Value` is a number that can be represented by f64.
///
/// For any Value on which `is_f64` returns true, `as_f64` is guaranteed to
/// return the floating point value.
///
/// Currently this function returns true if and only if both `is_i64` and
/// `is_u64` return false but this is not a guarantee in the future.
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("256.01").unwrap();
/// assert!(v.is_f64());
/// ```
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("true").unwrap();
/// assert!(!v.is_f64());
/// ```
pub fn is_f64(&self) -> bool {
match self.untag_ref() {
Value::Number(n) => n.is_f64(),
_ => false,
}
}
/// If the `Value` is a number, represent it as f64 if possible. Returns
/// None otherwise.
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("13.37").unwrap();
/// assert_eq!(v.as_f64(), Some(13.37));
/// ```
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("false").unwrap();
/// assert_eq!(v.as_f64(), None);
/// ```
pub fn as_f64(&self) -> Option<f64> {
match self.untag_ref() {
Value::Number(i) => i.as_f64(),
_ => None,
}
}
/// Returns true if the `Value` is a String. Returns false otherwise.
///
/// For any Value on which `is_string` returns true, `as_str` is guaranteed
/// to return the string slice.
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("'lorem ipsum'").unwrap();
/// assert!(v.is_string());
/// ```
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("42").unwrap();
/// assert!(!v.is_string());
/// ```
pub fn is_string(&self) -> bool {
self.as_str().is_some()
}
/// If the `Value` is a String, returns the associated str. Returns None
/// otherwise.
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("'lorem ipsum'").unwrap();
/// assert_eq!(v.as_str(), Some("lorem ipsum"));
/// ```
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("false").unwrap();
/// assert_eq!(v.as_str(), None);
/// ```
pub fn as_str(&self) -> Option<&str> {
match self.untag_ref() {
Value::String(s) => Some(s),
_ => None,
}
}
/// Returns true if the `Value` is a sequence. Returns false otherwise.
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("[1, 2, 3]").unwrap();
/// assert!(v.is_sequence());
/// ```
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("true").unwrap();
/// assert!(!v.is_sequence());
/// ```
pub fn is_sequence(&self) -> bool {
self.as_sequence().is_some()
}
/// If the `Value` is a sequence, return a reference to it if possible.
/// Returns None otherwise.
///
/// ```
/// # use serde_yaml::{Value, Number};
/// let v: Value = serde_yaml::from_str("[1, 2]").unwrap();
/// assert_eq!(v.as_sequence(), Some(&vec![Value::Number(Number::from(1)), Value::Number(Number::from(2))]));
/// ```
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("false").unwrap();
/// assert_eq!(v.as_sequence(), None);
/// ```
pub fn as_sequence(&self) -> Option<&Sequence> {
match self.untag_ref() {
Value::Sequence(seq) => Some(seq),
_ => None,
}
}
/// If the `Value` is a sequence, return a mutable reference to it if
/// possible. Returns None otherwise.
///
/// ```
/// # use serde_yaml::{Value, Number};
/// let mut v: Value = serde_yaml::from_str("[1]").unwrap();
/// let s = v.as_sequence_mut().unwrap();
/// s.push(Value::Number(Number::from(2)));
/// assert_eq!(s, &vec![Value::Number(Number::from(1)), Value::Number(Number::from(2))]);
/// ```
///
/// ```
/// # use serde_yaml::Value;
/// let mut v: Value = serde_yaml::from_str("false").unwrap();
/// assert_eq!(v.as_sequence_mut(), None);
/// ```
pub fn as_sequence_mut(&mut self) -> Option<&mut Sequence> {
match self.untag_mut() {
Value::Sequence(seq) => Some(seq),
_ => None,
}
}
/// Returns true if the `Value` is a mapping. Returns false otherwise.
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("a: 42").unwrap();
/// assert!(v.is_mapping());
/// ```
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("true").unwrap();
/// assert!(!v.is_mapping());
/// ```
pub fn is_mapping(&self) -> bool {
self.as_mapping().is_some()
}
/// If the `Value` is a mapping, return a reference to it if possible.
/// Returns None otherwise.
///
/// ```
/// # use serde_yaml::{Value, Mapping, Number};
/// let v: Value = serde_yaml::from_str("a: 42").unwrap();
///
/// let mut expected = Mapping::new();
/// expected.insert(Value::String("a".into()),Value::Number(Number::from(42)));
///
/// assert_eq!(v.as_mapping(), Some(&expected));
/// ```
///
/// ```
/// # use serde_yaml::Value;
/// let v: Value = serde_yaml::from_str("false").unwrap();
/// assert_eq!(v.as_mapping(), None);
/// ```
pub fn as_mapping(&self) -> Option<&Mapping> {
match self.untag_ref() {
Value::Mapping(map) => Some(map),
_ => None,
}
}
/// If the `Value` is a mapping, return a reference to it if possible.
/// Returns None otherwise.
///
/// ```
/// # use serde_yaml::{Value, Mapping, Number};
/// let mut v: Value = serde_yaml::from_str("a: 42").unwrap();
/// let m = v.as_mapping_mut().unwrap();
/// m.insert(Value::String("b".into()), Value::Number(Number::from(21)));
///
/// let mut expected = Mapping::new();
/// expected.insert(Value::String("a".into()), Value::Number(Number::from(42)));
/// expected.insert(Value::String("b".into()), Value::Number(Number::from(21)));
///
/// assert_eq!(m, &expected);
/// ```
///
/// ```
/// # use serde_yaml::{Value, Mapping};
/// let mut v: Value = serde_yaml::from_str("false").unwrap();
/// assert_eq!(v.as_mapping_mut(), None);
/// ```
pub fn as_mapping_mut(&mut self) -> Option<&mut Mapping> {
match self.untag_mut() {
Value::Mapping(map) => Some(map),
_ => None,
}
}
/// Performs merging of `<<` keys into the surrounding mapping.
///
/// The intended use of this in YAML is described in
/// <https://yaml.org/type/merge.html>.
///
/// ```
/// use serde_yaml::Value;
///
/// let config = "\
/// tasks:
/// build: &webpack_shared
/// command: webpack
/// args: build
/// inputs:
/// - 'src/**/*'
/// start:
/// <<: *webpack_shared
/// args: start
/// ";
///
/// let mut value: Value = serde_yaml::from_str(config).unwrap();
/// value.apply_merge().unwrap();
///
/// assert_eq!(value["tasks"]["start"]["command"], "webpack");
/// assert_eq!(value["tasks"]["start"]["args"], "start");
/// ```
pub fn apply_merge(&mut self) -> Result<(), Error> {
let mut stack = Vec::new();
stack.push(self);
while let Some(node) = stack.pop() {
match node {
Value::Mapping(mapping) => {
match mapping.remove("<<") {
Some(Value::Mapping(merge)) => {
for (k, v) in merge {
mapping.entry(k).or_insert(v);
}
}
Some(Value::Sequence(sequence)) => {
for value in sequence {
match value {
Value::Mapping(merge) => {
for (k, v) in merge {
mapping.entry(k).or_insert(v);
}
}
Value::Sequence(_) => {
return Err(error::new(ErrorImpl::SequenceInMergeElement));
}
Value::Tagged(_) => {
return Err(error::new(ErrorImpl::TaggedInMerge));
}
_unexpected => {
return Err(error::new(ErrorImpl::ScalarInMergeElement));
}
}
}
}
None => {}
Some(Value::Tagged(_)) => return Err(error::new(ErrorImpl::TaggedInMerge)),
Some(_unexpected) => return Err(error::new(ErrorImpl::ScalarInMerge)),
}
stack.extend(mapping.values_mut());
}
Value::Sequence(sequence) => stack.extend(sequence),
Value::Tagged(tagged) => stack.push(&mut tagged.value),
_ => {}
}
}
Ok(())
}
}
impl Eq for Value {}
// NOTE: This impl must be kept consistent with HashLikeValue's Hash impl in
// mapping.rs in order for value[str] indexing to work.
impl Hash for Value {
fn hash<H: Hasher>(&self, state: &mut H) {
mem::discriminant(self).hash(state);
match self {
Value::Null => {}
Value::Bool(v) => v.hash(state),
Value::Number(v) => v.hash(state),
Value::String(v) => v.hash(state),
Value::Sequence(v) => v.hash(state),
Value::Mapping(v) => v.hash(state),
Value::Tagged(v) => v.hash(state),
}
}
}
impl<'de> IntoDeserializer<'de, Error> for Value {
type Deserializer = Self;
fn into_deserializer(self) -> Self::Deserializer {
self
}
}

View File

@@ -0,0 +1,87 @@
use crate::Value;
impl PartialEq<str> for Value {
/// Compare `str` with YAML value
///
/// # Examples
///
/// ```
/// # use serde_yaml::Value;
/// assert!(Value::String("lorem".into()) == *"lorem");
/// ```
fn eq(&self, other: &str) -> bool {
self.as_str().map_or(false, |s| s == other)
}
}
impl<'a> PartialEq<&'a str> for Value {
/// Compare `&str` with YAML value
///
/// # Examples
///
/// ```
/// # use serde_yaml::Value;
/// assert!(Value::String("lorem".into()) == "lorem");
/// ```
fn eq(&self, other: &&str) -> bool {
self.as_str().map_or(false, |s| s == *other)
}
}
impl PartialEq<String> for Value {
/// Compare YAML value with String
///
/// # Examples
///
/// ```
/// # use serde_yaml::Value;
/// assert!(Value::String("lorem".into()) == "lorem".to_string());
/// ```
fn eq(&self, other: &String) -> bool {
self.as_str().map_or(false, |s| s == other)
}
}
impl PartialEq<bool> for Value {
/// Compare YAML value with bool
///
/// # Examples
///
/// ```
/// # use serde_yaml::Value;
/// assert!(Value::Bool(true) == true);
/// ```
fn eq(&self, other: &bool) -> bool {
self.as_bool().map_or(false, |b| b == *other)
}
}
macro_rules! partialeq_numeric {
($([$($ty:ty)*], $conversion:ident, $base:ty)*) => {
$($(
impl PartialEq<$ty> for Value {
fn eq(&self, other: &$ty) -> bool {
self.$conversion().map_or(false, |i| i == (*other as $base))
}
}
impl<'a> PartialEq<$ty> for &'a Value {
fn eq(&self, other: &$ty) -> bool {
self.$conversion().map_or(false, |i| i == (*other as $base))
}
}
impl<'a> PartialEq<$ty> for &'a mut Value {
fn eq(&self, other: &$ty) -> bool {
self.$conversion().map_or(false, |i| i == (*other as $base))
}
}
)*)*
}
}
partialeq_numeric! {
[i8 i16 i32 i64 isize], as_i64, i64
[u8 u16 u32 u64 usize], as_u64, u64
[f32 f64], as_f64, f64
}

840
vendor/serde_yaml/src/value/ser.rs vendored Normal file
View File

@@ -0,0 +1,840 @@
use crate::error::{self, Error, ErrorImpl};
use crate::value::tagged::{self, MaybeTag};
use crate::value::{to_value, Mapping, Number, Sequence, Tag, TaggedValue, Value};
use serde::ser::{self, Serialize};
use std::fmt::Display;
use std::mem;
type Result<T, E = Error> = std::result::Result<T, E>;
impl Serialize for Value {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match self {
Value::Null => serializer.serialize_unit(),
Value::Bool(b) => serializer.serialize_bool(*b),
Value::Number(n) => n.serialize(serializer),
Value::String(s) => serializer.serialize_str(s),
Value::Sequence(seq) => seq.serialize(serializer),
Value::Mapping(mapping) => {
use serde::ser::SerializeMap;
let mut map = serializer.serialize_map(Some(mapping.len()))?;
for (k, v) in mapping {
map.serialize_entry(k, v)?;
}
map.end()
}
Value::Tagged(tagged) => tagged.serialize(serializer),
}
}
}
/// Serializer whose output is a `Value`.
///
/// This is the serializer that backs [`serde_yaml::to_value`][crate::to_value].
/// Unlike the main serde_yaml serializer which goes from some serializable
/// value of type `T` to YAML text, this one goes from `T` to
/// `serde_yaml::Value`.
///
/// The `to_value` function is implementable as:
///
/// ```
/// use serde::Serialize;
/// use serde_yaml::{Error, Value};
///
/// pub fn to_value<T>(input: T) -> Result<Value, Error>
/// where
/// T: Serialize,
/// {
/// input.serialize(serde_yaml::value::Serializer)
/// }
/// ```
pub struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Value;
type Error = Error;
type SerializeSeq = SerializeArray;
type SerializeTuple = SerializeArray;
type SerializeTupleStruct = SerializeArray;
type SerializeTupleVariant = SerializeTupleVariant;
type SerializeMap = SerializeMap;
type SerializeStruct = SerializeStruct;
type SerializeStructVariant = SerializeStructVariant;
fn serialize_bool(self, v: bool) -> Result<Value> {
Ok(Value::Bool(v))
}
fn serialize_i8(self, v: i8) -> Result<Value> {
Ok(Value::Number(Number::from(v)))
}
fn serialize_i16(self, v: i16) -> Result<Value> {
Ok(Value::Number(Number::from(v)))
}
fn serialize_i32(self, v: i32) -> Result<Value> {
Ok(Value::Number(Number::from(v)))
}
fn serialize_i64(self, v: i64) -> Result<Value> {
Ok(Value::Number(Number::from(v)))
}
fn serialize_i128(self, v: i128) -> Result<Value> {
if let Ok(v) = u64::try_from(v) {
self.serialize_u64(v)
} else if let Ok(v) = i64::try_from(v) {
self.serialize_i64(v)
} else {
Ok(Value::String(v.to_string()))
}
}
fn serialize_u8(self, v: u8) -> Result<Value> {
Ok(Value::Number(Number::from(v)))
}
fn serialize_u16(self, v: u16) -> Result<Value> {
Ok(Value::Number(Number::from(v)))
}
fn serialize_u32(self, v: u32) -> Result<Value> {
Ok(Value::Number(Number::from(v)))
}
fn serialize_u64(self, v: u64) -> Result<Value> {
Ok(Value::Number(Number::from(v)))
}
fn serialize_u128(self, v: u128) -> Result<Value> {
if let Ok(v) = u64::try_from(v) {
self.serialize_u64(v)
} else {
Ok(Value::String(v.to_string()))
}
}
fn serialize_f32(self, v: f32) -> Result<Value> {
Ok(Value::Number(Number::from(v)))
}
fn serialize_f64(self, v: f64) -> Result<Value> {
Ok(Value::Number(Number::from(v)))
}
fn serialize_char(self, value: char) -> Result<Value> {
Ok(Value::String(value.to_string()))
}
fn serialize_str(self, value: &str) -> Result<Value> {
Ok(Value::String(value.to_owned()))
}
fn serialize_bytes(self, value: &[u8]) -> Result<Value> {
let vec = value
.iter()
.map(|&b| Value::Number(Number::from(b)))
.collect();
Ok(Value::Sequence(vec))
}
fn serialize_unit(self) -> Result<Value> {
Ok(Value::Null)
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<Value> {
self.serialize_unit()
}
fn serialize_unit_variant(
self,
_name: &str,
_variant_index: u32,
variant: &str,
) -> Result<Value> {
Ok(Value::String(variant.to_owned()))
}
fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<Value>
where
T: ?Sized + ser::Serialize,
{
value.serialize(self)
}
fn serialize_newtype_variant<T>(
self,
_name: &str,
_variant_index: u32,
variant: &str,
value: &T,
) -> Result<Value>
where
T: ?Sized + ser::Serialize,
{
if variant.is_empty() {
return Err(error::new(ErrorImpl::EmptyTag));
}
Ok(Value::Tagged(Box::new(TaggedValue {
tag: Tag::new(variant),
value: to_value(value)?,
})))
}
fn serialize_none(self) -> Result<Value> {
self.serialize_unit()
}
fn serialize_some<V>(self, value: &V) -> Result<Value>
where
V: ?Sized + ser::Serialize,
{
value.serialize(self)
}
fn serialize_seq(self, len: Option<usize>) -> Result<SerializeArray> {
let sequence = match len {
None => Sequence::new(),
Some(len) => Sequence::with_capacity(len),
};
Ok(SerializeArray { sequence })
}
fn serialize_tuple(self, len: usize) -> Result<SerializeArray> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_struct(self, _name: &'static str, len: usize) -> Result<SerializeArray> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_variant(
self,
_enum: &'static str,
_idx: u32,
variant: &'static str,
len: usize,
) -> Result<SerializeTupleVariant> {
if variant.is_empty() {
return Err(error::new(ErrorImpl::EmptyTag));
}
Ok(SerializeTupleVariant {
tag: variant,
sequence: Sequence::with_capacity(len),
})
}
fn serialize_map(self, len: Option<usize>) -> Result<SerializeMap> {
if len == Some(1) {
Ok(SerializeMap::CheckForTag)
} else {
Ok(SerializeMap::Untagged {
mapping: Mapping::new(),
next_key: None,
})
}
}
fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<SerializeStruct> {
Ok(SerializeStruct {
mapping: Mapping::new(),
})
}
fn serialize_struct_variant(
self,
_enum: &'static str,
_idx: u32,
variant: &'static str,
_len: usize,
) -> Result<SerializeStructVariant> {
if variant.is_empty() {
return Err(error::new(ErrorImpl::EmptyTag));
}
Ok(SerializeStructVariant {
tag: variant,
mapping: Mapping::new(),
})
}
}
pub struct SerializeArray {
sequence: Sequence,
}
impl ser::SerializeSeq for SerializeArray {
type Ok = Value;
type Error = Error;
fn serialize_element<T>(&mut self, elem: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
self.sequence.push(to_value(elem)?);
Ok(())
}
fn end(self) -> Result<Value> {
Ok(Value::Sequence(self.sequence))
}
}
impl ser::SerializeTuple for SerializeArray {
type Ok = Value;
type Error = Error;
fn serialize_element<T>(&mut self, elem: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
ser::SerializeSeq::serialize_element(self, elem)
}
fn end(self) -> Result<Value> {
ser::SerializeSeq::end(self)
}
}
impl ser::SerializeTupleStruct for SerializeArray {
type Ok = Value;
type Error = Error;
fn serialize_field<V>(&mut self, value: &V) -> Result<()>
where
V: ?Sized + ser::Serialize,
{
ser::SerializeSeq::serialize_element(self, value)
}
fn end(self) -> Result<Value> {
ser::SerializeSeq::end(self)
}
}
pub struct SerializeTupleVariant {
tag: &'static str,
sequence: Sequence,
}
impl ser::SerializeTupleVariant for SerializeTupleVariant {
type Ok = Value;
type Error = Error;
fn serialize_field<V>(&mut self, v: &V) -> Result<()>
where
V: ?Sized + ser::Serialize,
{
self.sequence.push(to_value(v)?);
Ok(())
}
fn end(self) -> Result<Value> {
Ok(Value::Tagged(Box::new(TaggedValue {
tag: Tag::new(self.tag),
value: Value::Sequence(self.sequence),
})))
}
}
pub enum SerializeMap {
CheckForTag,
Tagged(TaggedValue),
Untagged {
mapping: Mapping,
next_key: Option<Value>,
},
}
impl ser::SerializeMap for SerializeMap {
type Ok = Value;
type Error = Error;
fn serialize_key<T>(&mut self, key: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
let key = Some(to_value(key)?);
match self {
SerializeMap::CheckForTag => {
*self = SerializeMap::Untagged {
mapping: Mapping::new(),
next_key: key,
};
}
SerializeMap::Tagged(tagged) => {
let mut mapping = Mapping::new();
mapping.insert(
Value::String(tagged.tag.to_string()),
mem::take(&mut tagged.value),
);
*self = SerializeMap::Untagged {
mapping,
next_key: key,
};
}
SerializeMap::Untagged { next_key, .. } => *next_key = key,
}
Ok(())
}
fn serialize_value<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
let (mapping, key) = match self {
SerializeMap::CheckForTag | SerializeMap::Tagged(_) => unreachable!(),
SerializeMap::Untagged { mapping, next_key } => (mapping, next_key),
};
match key.take() {
Some(key) => mapping.insert(key, to_value(value)?),
None => panic!("serialize_value called before serialize_key"),
};
Ok(())
}
fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<()>
where
K: ?Sized + ser::Serialize,
V: ?Sized + ser::Serialize,
{
struct CheckForTag;
struct NotTag<T> {
delegate: T,
}
impl ser::Serializer for CheckForTag {
type Ok = MaybeTag<Value>;
type Error = Error;
type SerializeSeq = NotTag<SerializeArray>;
type SerializeTuple = NotTag<SerializeArray>;
type SerializeTupleStruct = NotTag<SerializeArray>;
type SerializeTupleVariant = NotTag<SerializeTupleVariant>;
type SerializeMap = NotTag<SerializeMap>;
type SerializeStruct = NotTag<SerializeStruct>;
type SerializeStructVariant = NotTag<SerializeStructVariant>;
fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
Serializer.serialize_bool(v).map(MaybeTag::NotTag)
}
fn serialize_i8(self, v: i8) -> Result<Self::Ok> {
Serializer.serialize_i8(v).map(MaybeTag::NotTag)
}
fn serialize_i16(self, v: i16) -> Result<Self::Ok> {
Serializer.serialize_i16(v).map(MaybeTag::NotTag)
}
fn serialize_i32(self, v: i32) -> Result<Self::Ok> {
Serializer.serialize_i32(v).map(MaybeTag::NotTag)
}
fn serialize_i64(self, v: i64) -> Result<Self::Ok> {
Serializer.serialize_i64(v).map(MaybeTag::NotTag)
}
fn serialize_i128(self, v: i128) -> Result<Self::Ok> {
Serializer.serialize_i128(v).map(MaybeTag::NotTag)
}
fn serialize_u8(self, v: u8) -> Result<Self::Ok> {
Serializer.serialize_u8(v).map(MaybeTag::NotTag)
}
fn serialize_u16(self, v: u16) -> Result<Self::Ok> {
Serializer.serialize_u16(v).map(MaybeTag::NotTag)
}
fn serialize_u32(self, v: u32) -> Result<Self::Ok> {
Serializer.serialize_u32(v).map(MaybeTag::NotTag)
}
fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
Serializer.serialize_u64(v).map(MaybeTag::NotTag)
}
fn serialize_u128(self, v: u128) -> Result<Self::Ok> {
Serializer.serialize_u128(v).map(MaybeTag::NotTag)
}
fn serialize_f32(self, v: f32) -> Result<Self::Ok> {
Serializer.serialize_f32(v).map(MaybeTag::NotTag)
}
fn serialize_f64(self, v: f64) -> Result<Self::Ok> {
Serializer.serialize_f64(v).map(MaybeTag::NotTag)
}
fn serialize_char(self, value: char) -> Result<Self::Ok> {
Serializer.serialize_char(value).map(MaybeTag::NotTag)
}
fn serialize_str(self, value: &str) -> Result<Self::Ok> {
Serializer.serialize_str(value).map(MaybeTag::NotTag)
}
fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok> {
Serializer.serialize_bytes(value).map(MaybeTag::NotTag)
}
fn serialize_unit(self) -> Result<Self::Ok> {
Serializer.serialize_unit().map(MaybeTag::NotTag)
}
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> {
Serializer.serialize_unit_struct(name).map(MaybeTag::NotTag)
}
fn serialize_unit_variant(
self,
name: &'static str,
variant_index: u32,
variant: &'static str,
) -> Result<Self::Ok> {
Serializer
.serialize_unit_variant(name, variant_index, variant)
.map(MaybeTag::NotTag)
}
fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<Self::Ok>
where
T: ?Sized + ser::Serialize,
{
Serializer
.serialize_newtype_struct(name, value)
.map(MaybeTag::NotTag)
}
fn serialize_newtype_variant<T>(
self,
name: &'static str,
variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<Self::Ok>
where
T: ?Sized + ser::Serialize,
{
Serializer
.serialize_newtype_variant(name, variant_index, variant, value)
.map(MaybeTag::NotTag)
}
fn serialize_none(self) -> Result<Self::Ok> {
Serializer.serialize_none().map(MaybeTag::NotTag)
}
fn serialize_some<V>(self, value: &V) -> Result<Self::Ok>
where
V: ?Sized + ser::Serialize,
{
Serializer.serialize_some(value).map(MaybeTag::NotTag)
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
Ok(NotTag {
delegate: Serializer.serialize_seq(len)?,
})
}
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
Ok(NotTag {
delegate: Serializer.serialize_tuple(len)?,
})
}
fn serialize_tuple_struct(
self,
name: &'static str,
len: usize,
) -> Result<Self::SerializeTupleStruct> {
Ok(NotTag {
delegate: Serializer.serialize_tuple_struct(name, len)?,
})
}
fn serialize_tuple_variant(
self,
name: &'static str,
variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeTupleVariant> {
Ok(NotTag {
delegate: Serializer.serialize_tuple_variant(
name,
variant_index,
variant,
len,
)?,
})
}
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
Ok(NotTag {
delegate: Serializer.serialize_map(len)?,
})
}
fn serialize_struct(
self,
name: &'static str,
len: usize,
) -> Result<Self::SerializeStruct> {
Ok(NotTag {
delegate: Serializer.serialize_struct(name, len)?,
})
}
fn serialize_struct_variant(
self,
name: &'static str,
variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeStructVariant> {
Ok(NotTag {
delegate: Serializer.serialize_struct_variant(
name,
variant_index,
variant,
len,
)?,
})
}
fn collect_str<T>(self, value: &T) -> Result<Self::Ok>
where
T: ?Sized + Display,
{
Ok(match tagged::check_for_tag(value) {
MaybeTag::Tag(tag) => MaybeTag::Tag(tag),
MaybeTag::NotTag(string) => MaybeTag::NotTag(Value::String(string)),
})
}
}
impl ser::SerializeSeq for NotTag<SerializeArray> {
type Ok = MaybeTag<Value>;
type Error = Error;
fn serialize_element<T>(&mut self, elem: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
self.delegate.serialize_element(elem)
}
fn end(self) -> Result<Self::Ok> {
self.delegate.end().map(MaybeTag::NotTag)
}
}
impl ser::SerializeTuple for NotTag<SerializeArray> {
type Ok = MaybeTag<Value>;
type Error = Error;
fn serialize_element<T>(&mut self, elem: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
self.delegate.serialize_element(elem)
}
fn end(self) -> Result<Self::Ok> {
self.delegate.end().map(MaybeTag::NotTag)
}
}
impl ser::SerializeTupleStruct for NotTag<SerializeArray> {
type Ok = MaybeTag<Value>;
type Error = Error;
fn serialize_field<V>(&mut self, value: &V) -> Result<()>
where
V: ?Sized + ser::Serialize,
{
self.delegate.serialize_field(value)
}
fn end(self) -> Result<Self::Ok> {
self.delegate.end().map(MaybeTag::NotTag)
}
}
impl ser::SerializeTupleVariant for NotTag<SerializeTupleVariant> {
type Ok = MaybeTag<Value>;
type Error = Error;
fn serialize_field<V>(&mut self, v: &V) -> Result<()>
where
V: ?Sized + ser::Serialize,
{
self.delegate.serialize_field(v)
}
fn end(self) -> Result<Self::Ok> {
self.delegate.end().map(MaybeTag::NotTag)
}
}
impl ser::SerializeMap for NotTag<SerializeMap> {
type Ok = MaybeTag<Value>;
type Error = Error;
fn serialize_key<T>(&mut self, key: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
self.delegate.serialize_key(key)
}
fn serialize_value<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
self.delegate.serialize_value(value)
}
fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<()>
where
K: ?Sized + ser::Serialize,
V: ?Sized + ser::Serialize,
{
self.delegate.serialize_entry(key, value)
}
fn end(self) -> Result<Self::Ok> {
self.delegate.end().map(MaybeTag::NotTag)
}
}
impl ser::SerializeStruct for NotTag<SerializeStruct> {
type Ok = MaybeTag<Value>;
type Error = Error;
fn serialize_field<V>(&mut self, key: &'static str, value: &V) -> Result<()>
where
V: ?Sized + ser::Serialize,
{
self.delegate.serialize_field(key, value)
}
fn end(self) -> Result<Self::Ok> {
self.delegate.end().map(MaybeTag::NotTag)
}
}
impl ser::SerializeStructVariant for NotTag<SerializeStructVariant> {
type Ok = MaybeTag<Value>;
type Error = Error;
fn serialize_field<V>(&mut self, field: &'static str, v: &V) -> Result<()>
where
V: ?Sized + ser::Serialize,
{
self.delegate.serialize_field(field, v)
}
fn end(self) -> Result<Self::Ok> {
self.delegate.end().map(MaybeTag::NotTag)
}
}
match self {
SerializeMap::CheckForTag => {
let key = key.serialize(CheckForTag)?;
let mut mapping = Mapping::new();
*self = match key {
MaybeTag::Tag(string) => SerializeMap::Tagged(TaggedValue {
tag: Tag::new(string),
value: to_value(value)?,
}),
MaybeTag::NotTag(key) => {
mapping.insert(key, to_value(value)?);
SerializeMap::Untagged {
mapping,
next_key: None,
}
}
};
}
SerializeMap::Tagged(tagged) => {
let mut mapping = Mapping::new();
mapping.insert(
Value::String(tagged.tag.to_string()),
mem::take(&mut tagged.value),
);
mapping.insert(to_value(key)?, to_value(value)?);
*self = SerializeMap::Untagged {
mapping,
next_key: None,
};
}
SerializeMap::Untagged { mapping, .. } => {
mapping.insert(to_value(key)?, to_value(value)?);
}
}
Ok(())
}
fn end(self) -> Result<Value> {
Ok(match self {
SerializeMap::CheckForTag => Value::Mapping(Mapping::new()),
SerializeMap::Tagged(tagged) => Value::Tagged(Box::new(tagged)),
SerializeMap::Untagged { mapping, .. } => Value::Mapping(mapping),
})
}
}
pub struct SerializeStruct {
mapping: Mapping,
}
impl ser::SerializeStruct for SerializeStruct {
type Ok = Value;
type Error = Error;
fn serialize_field<V>(&mut self, key: &'static str, value: &V) -> Result<()>
where
V: ?Sized + ser::Serialize,
{
self.mapping.insert(to_value(key)?, to_value(value)?);
Ok(())
}
fn end(self) -> Result<Value> {
Ok(Value::Mapping(self.mapping))
}
}
pub struct SerializeStructVariant {
tag: &'static str,
mapping: Mapping,
}
impl ser::SerializeStructVariant for SerializeStructVariant {
type Ok = Value;
type Error = Error;
fn serialize_field<V>(&mut self, field: &'static str, v: &V) -> Result<()>
where
V: ?Sized + ser::Serialize,
{
self.mapping.insert(to_value(field)?, to_value(v)?);
Ok(())
}
fn end(self) -> Result<Value> {
Ok(Value::Tagged(Box::new(TaggedValue {
tag: Tag::new(self.tag),
value: Value::Mapping(self.mapping),
})))
}
}

474
vendor/serde_yaml/src/value/tagged.rs vendored Normal file
View File

@@ -0,0 +1,474 @@
use crate::value::de::{MapDeserializer, MapRefDeserializer, SeqDeserializer, SeqRefDeserializer};
use crate::value::Value;
use crate::Error;
use serde::de::value::{BorrowedStrDeserializer, StrDeserializer};
use serde::de::{
Deserialize, DeserializeSeed, Deserializer, EnumAccess, Error as _, VariantAccess, Visitor,
};
use serde::forward_to_deserialize_any;
use serde::ser::{Serialize, SerializeMap, Serializer};
use std::cmp::Ordering;
use std::fmt::{self, Debug, Display};
use std::hash::{Hash, Hasher};
use std::mem;
/// A representation of YAML's `!Tag` syntax, used for enums.
///
/// Refer to the example code on [`TaggedValue`] for an example of deserializing
/// tagged values.
#[derive(Clone)]
pub struct Tag {
pub(crate) string: String,
}
/// A `Tag` + `Value` representing a tagged YAML scalar, sequence, or mapping.
///
/// ```
/// use serde_yaml::value::TaggedValue;
/// use std::collections::BTreeMap;
///
/// let yaml = "
/// scalar: !Thing x
/// sequence_flow: !Thing [first]
/// sequence_block: !Thing
/// - first
/// mapping_flow: !Thing {k: v}
/// mapping_block: !Thing
/// k: v
/// ";
///
/// let data: BTreeMap<String, TaggedValue> = serde_yaml::from_str(yaml).unwrap();
/// assert!(data["scalar"].tag == "Thing");
/// assert!(data["sequence_flow"].tag == "Thing");
/// assert!(data["sequence_block"].tag == "Thing");
/// assert!(data["mapping_flow"].tag == "Thing");
/// assert!(data["mapping_block"].tag == "Thing");
///
/// // The leading '!' in tags are not significant. The following is also true.
/// assert!(data["scalar"].tag == "!Thing");
/// ```
#[derive(Clone, PartialEq, PartialOrd, Hash, Debug)]
pub struct TaggedValue {
#[allow(missing_docs)]
pub tag: Tag,
#[allow(missing_docs)]
pub value: Value,
}
impl Tag {
/// Create tag.
///
/// The leading '!' is not significant. It may be provided, but does not
/// have to be. The following are equivalent:
///
/// ```
/// use serde_yaml::value::Tag;
///
/// assert_eq!(Tag::new("!Thing"), Tag::new("Thing"));
///
/// let tag = Tag::new("Thing");
/// assert!(tag == "Thing");
/// assert!(tag == "!Thing");
/// assert!(tag.to_string() == "!Thing");
///
/// let tag = Tag::new("!Thing");
/// assert!(tag == "Thing");
/// assert!(tag == "!Thing");
/// assert!(tag.to_string() == "!Thing");
/// ```
///
/// Such a tag would serialize to `!Thing` in YAML regardless of whether a
/// '!' was included in the call to `Tag::new`.
///
/// # Panics
///
/// Panics if `string.is_empty()`. There is no syntax in YAML for an empty
/// tag.
pub fn new(string: impl Into<String>) -> Self {
let tag: String = string.into();
assert!(!tag.is_empty(), "empty YAML tag is not allowed");
Tag { string: tag }
}
}
impl Value {
pub(crate) fn untag(self) -> Self {
let mut cur = self;
while let Value::Tagged(tagged) = cur {
cur = tagged.value;
}
cur
}
pub(crate) fn untag_ref(&self) -> &Self {
let mut cur = self;
while let Value::Tagged(tagged) = cur {
cur = &tagged.value;
}
cur
}
pub(crate) fn untag_mut(&mut self) -> &mut Self {
let mut cur = self;
while let Value::Tagged(tagged) = cur {
cur = &mut tagged.value;
}
cur
}
}
pub(crate) fn nobang(maybe_banged: &str) -> &str {
match maybe_banged.strip_prefix('!') {
Some("") | None => maybe_banged,
Some(unbanged) => unbanged,
}
}
impl Eq for Tag {}
impl PartialEq for Tag {
fn eq(&self, other: &Tag) -> bool {
PartialEq::eq(nobang(&self.string), nobang(&other.string))
}
}
impl<T> PartialEq<T> for Tag
where
T: ?Sized + AsRef<str>,
{
fn eq(&self, other: &T) -> bool {
PartialEq::eq(nobang(&self.string), nobang(other.as_ref()))
}
}
impl Ord for Tag {
fn cmp(&self, other: &Self) -> Ordering {
Ord::cmp(nobang(&self.string), nobang(&other.string))
}
}
impl PartialOrd for Tag {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Hash for Tag {
fn hash<H: Hasher>(&self, hasher: &mut H) {
nobang(&self.string).hash(hasher);
}
}
impl Display for Tag {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "!{}", nobang(&self.string))
}
}
impl Debug for Tag {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(self, formatter)
}
}
impl Serialize for TaggedValue {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
struct SerializeTag<'a>(&'a Tag);
impl<'a> Serialize for SerializeTag<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.collect_str(self.0)
}
}
let mut map = serializer.serialize_map(Some(1))?;
map.serialize_entry(&SerializeTag(&self.tag), &self.value)?;
map.end()
}
}
impl<'de> Deserialize<'de> for TaggedValue {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct TaggedValueVisitor;
impl<'de> Visitor<'de> for TaggedValueVisitor {
type Value = TaggedValue;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a YAML value with a !Tag")
}
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
where
A: EnumAccess<'de>,
{
let (tag, contents) = data.variant_seed(TagStringVisitor)?;
let value = contents.newtype_variant()?;
Ok(TaggedValue { tag, value })
}
}
deserializer.deserialize_any(TaggedValueVisitor)
}
}
impl<'de> Deserializer<'de> for TaggedValue {
type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
visitor.visit_enum(self)
}
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
drop(self);
visitor.visit_unit()
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct
map struct enum identifier
}
}
impl<'de> EnumAccess<'de> for TaggedValue {
type Error = Error;
type Variant = Value;
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Error>
where
V: DeserializeSeed<'de>,
{
let tag = StrDeserializer::<Error>::new(nobang(&self.tag.string));
let value = seed.deserialize(tag)?;
Ok((value, self.value))
}
}
impl<'de> VariantAccess<'de> for Value {
type Error = Error;
fn unit_variant(self) -> Result<(), Error> {
Deserialize::deserialize(self)
}
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Error>
where
T: DeserializeSeed<'de>,
{
seed.deserialize(self)
}
fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
if let Value::Sequence(v) = self {
Deserializer::deserialize_any(SeqDeserializer::new(v), visitor)
} else {
Err(Error::invalid_type(self.unexpected(), &"tuple variant"))
}
}
fn struct_variant<V>(
self,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
if let Value::Mapping(v) = self {
Deserializer::deserialize_any(MapDeserializer::new(v), visitor)
} else {
Err(Error::invalid_type(self.unexpected(), &"struct variant"))
}
}
}
impl<'de> Deserializer<'de> for &'de TaggedValue {
type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
visitor.visit_enum(self)
}
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
visitor.visit_unit()
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct
map struct enum identifier
}
}
impl<'de> EnumAccess<'de> for &'de TaggedValue {
type Error = Error;
type Variant = &'de Value;
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Error>
where
V: DeserializeSeed<'de>,
{
let tag = BorrowedStrDeserializer::<Error>::new(nobang(&self.tag.string));
let value = seed.deserialize(tag)?;
Ok((value, &self.value))
}
}
impl<'de> VariantAccess<'de> for &'de Value {
type Error = Error;
fn unit_variant(self) -> Result<(), Error> {
Deserialize::deserialize(self)
}
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Error>
where
T: DeserializeSeed<'de>,
{
seed.deserialize(self)
}
fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
if let Value::Sequence(v) = self {
Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor)
} else {
Err(Error::invalid_type(self.unexpected(), &"tuple variant"))
}
}
fn struct_variant<V>(
self,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
if let Value::Mapping(v) = self {
Deserializer::deserialize_any(MapRefDeserializer::new(v), visitor)
} else {
Err(Error::invalid_type(self.unexpected(), &"struct variant"))
}
}
}
pub(crate) struct TagStringVisitor;
impl<'de> Visitor<'de> for TagStringVisitor {
type Value = Tag;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a YAML tag string")
}
fn visit_str<E>(self, string: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_string(string.to_owned())
}
fn visit_string<E>(self, string: String) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
if string.is_empty() {
return Err(E::custom("empty YAML tag is not allowed"));
}
Ok(Tag::new(string))
}
}
impl<'de> DeserializeSeed<'de> for TagStringVisitor {
type Value = Tag;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_string(self)
}
}
pub(crate) enum MaybeTag<T> {
Tag(String),
NotTag(T),
}
pub(crate) fn check_for_tag<T>(value: &T) -> MaybeTag<String>
where
T: ?Sized + Display,
{
enum CheckForTag {
Empty,
Bang,
Tag(String),
NotTag(String),
}
impl fmt::Write for CheckForTag {
fn write_str(&mut self, s: &str) -> fmt::Result {
if s.is_empty() {
return Ok(());
}
match self {
CheckForTag::Empty => {
if s == "!" {
*self = CheckForTag::Bang;
} else {
*self = CheckForTag::NotTag(s.to_owned());
}
}
CheckForTag::Bang => {
*self = CheckForTag::Tag(s.to_owned());
}
CheckForTag::Tag(string) => {
let mut string = mem::take(string);
string.push_str(s);
*self = CheckForTag::NotTag(string);
}
CheckForTag::NotTag(string) => {
string.push_str(s);
}
}
Ok(())
}
}
let mut check_for_tag = CheckForTag::Empty;
fmt::write(&mut check_for_tag, format_args!("{}", value)).unwrap();
match check_for_tag {
CheckForTag::Empty => MaybeTag::NotTag(String::new()),
CheckForTag::Bang => MaybeTag::NotTag("!".to_owned()),
CheckForTag::Tag(string) => MaybeTag::Tag(string),
CheckForTag::NotTag(string) => MaybeTag::NotTag(string),
}
}

2124
vendor/serde_yaml/src/with.rs vendored Normal file

File diff suppressed because it is too large Load Diff