use crate::error::Error;
use crate::event::{Event, ScalarStyle};
use crate::pos::{Pos, Span};
use std::borrow::Cow;
#[expect(
clippy::large_enum_variant,
reason = "Yield carries Event<'input> which grows with each new span field; boxing would require widespread call-site changes for an internal type"
)]
pub enum StepResult<'input> {
Continue,
Yield(Result<(Event<'input>, Span), Error>),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum IterState {
BeforeStream,
BetweenDocs,
InDocument,
Done,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MappingPhase {
Key,
Value,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CollectionEntry {
Sequence(usize, bool),
Mapping(usize, MappingPhase, bool),
}
impl CollectionEntry {
pub const fn indent(self) -> usize {
match self {
Self::Sequence(col, _) | Self::Mapping(col, _, _) => col,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FlowMappingPhase {
Key,
Value,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PendingAnchor<'input> {
Standalone(&'input str, Span),
Inline(&'input str, Span),
}
impl<'input> PendingAnchor<'input> {
pub const fn name(self) -> &'input str {
match self {
Self::Standalone(n, _) | Self::Inline(n, _) => n,
}
}
pub const fn loc(self) -> Span {
match self {
Self::Standalone(_, s) | Self::Inline(_, s) => s,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum PendingTag<'input> {
Standalone(Cow<'input, str>, Span),
Inline(Cow<'input, str>, Span),
}
impl<'input> PendingTag<'input> {
pub fn into_cow(self) -> Cow<'input, str> {
match self {
Self::Standalone(c, _) | Self::Inline(c, _) => c,
}
}
pub const fn loc(&self) -> Span {
match self {
Self::Standalone(_, s) | Self::Inline(_, s) => *s,
}
}
}
pub enum ConsumedMapping<'input> {
ExplicitKey,
ImplicitKey {
key_value: std::borrow::Cow<'input, str>,
key_style: ScalarStyle,
key_span: Span,
},
InlineImplicitMappingError { pos: Pos },
QuotedKeyError { pos: Pos, message: String },
}
#[cfg(test)]
mod tests {
use super::{PendingAnchor, PendingTag};
use crate::pos::{Pos, Span};
use std::borrow::Cow;
const TEST_SPAN: Span = Span {
start: Pos {
byte_offset: 0,
line: 1,
column: 0,
},
end: Pos {
byte_offset: 7,
line: 1,
column: 7,
},
};
#[test]
fn pending_anchor_standalone_carries_name() {
let a = PendingAnchor::Standalone("myanchor", TEST_SPAN);
assert_eq!(a.name(), "myanchor");
assert!(matches!(a, PendingAnchor::Standalone("myanchor", _)));
}
#[test]
fn pending_anchor_inline_carries_name() {
let a = PendingAnchor::Inline("inlineanchor", TEST_SPAN);
assert_eq!(a.name(), "inlineanchor");
assert!(matches!(a, PendingAnchor::Inline("inlineanchor", _)));
}
#[test]
fn pending_anchor_none_matches_none_arm() {
let a: Option<PendingAnchor<'_>> = None;
assert!(a.is_none());
assert!(!matches!(a, Some(PendingAnchor::Standalone(..))));
assert!(!matches!(a, Some(PendingAnchor::Inline(..))));
}
#[test]
fn pending_anchor_standalone_loc_returns_span() {
let span = Span {
start: Pos {
byte_offset: 5,
line: 2,
column: 3,
},
end: Pos {
byte_offset: 12,
line: 2,
column: 10,
},
};
let a = PendingAnchor::Standalone("anchor", span);
assert_eq!(a.loc(), span);
}
#[test]
fn pending_anchor_inline_loc_returns_span() {
let span = Span {
start: Pos {
byte_offset: 10,
line: 3,
column: 0,
},
end: Pos {
byte_offset: 17,
line: 3,
column: 7,
},
};
let a = PendingAnchor::Inline("anchor", span);
assert_eq!(a.loc(), span);
}
fn dummy_span() -> Span {
Span {
start: Pos {
byte_offset: 0,
line: 1,
column: 0,
},
end: Pos {
byte_offset: 1,
line: 1,
column: 1,
},
}
}
#[test]
fn pending_tag_standalone_carries_value() {
let tag = PendingTag::Standalone(Cow::Borrowed("tag:yaml.org,2002:str"), dummy_span());
assert!(
matches!(&tag, PendingTag::Standalone(c, _) if c.as_ref() == "tag:yaml.org,2002:str")
);
assert_eq!(tag.into_cow().as_ref(), "tag:yaml.org,2002:str");
}
#[test]
fn pending_tag_inline_carries_value() {
let tag = PendingTag::Inline(Cow::Borrowed("!mytag"), dummy_span());
assert!(matches!(&tag, PendingTag::Inline(c, _) if c.as_ref() == "!mytag"));
assert_eq!(tag.into_cow().as_ref(), "!mytag");
}
#[test]
fn pending_tag_standalone_loc_returns_span() {
let span = Span {
start: Pos {
byte_offset: 5,
line: 2,
column: 3,
},
end: Pos {
byte_offset: 12,
line: 2,
column: 10,
},
};
let tag = PendingTag::Standalone(Cow::Borrowed("!!str"), span);
assert_eq!(tag.loc(), span);
}
#[test]
fn pending_tag_inline_loc_returns_span() {
let span = Span {
start: Pos {
byte_offset: 10,
line: 3,
column: 0,
},
end: Pos {
byte_offset: 17,
line: 3,
column: 7,
},
};
let tag = PendingTag::Inline(Cow::Borrowed("!mytag"), span);
assert_eq!(tag.loc(), span);
}
}