pub struct AnnotatedArray<'a> { /* private fields */ }Expand description
Bundles the optional type-ascription inputs for array construction.
A ParserContext implementation receives one of these in
ParserContext::make_annotated_array and decides how to consume it: an implementation that
needs runtime array metadata immediately resolves it with
resolve_element_type; one that defers semantic checking keeps
the syntax with into_parts.
§Examples
use cel_parser::{ExprSpan, TypeExpr};
use cel_parser::parser_context::AnnotatedArray;
use proc_macro2::Span;
fn ignore(_: &TypeExpr) -> cel_parser::Result<cel_parser::ResolvedArrayType> {
unreachable!("this example only inspects stored syntax")
}
let span = ExprSpan {
start: Span::call_site(),
end: Span::call_site(),
};
let mut resolve = ignore;
let annotation = AnnotatedArray::new(
&mut resolve,
Some(TypeExpr::Array {
element: Box::new(TypeExpr::Named {
name: "i32".to_string(),
args: Vec::new(),
span,
}),
span,
}),
Some(span),
);
assert!(matches!(annotation.type_annotation(), Some(TypeExpr::Array { .. })));
assert!(annotation.annotation_span().is_some());Implementations§
Source§impl<'a> AnnotatedArray<'a>
impl<'a> AnnotatedArray<'a>
Sourcepub fn new(
resolve_array_type: &'a mut dyn FnMut(&TypeExpr) -> Result<ResolvedArrayType>,
type_annotation: Option<TypeExpr>,
annotation_span: Option<ExprSpan>,
) -> Self
pub fn new( resolve_array_type: &'a mut dyn FnMut(&TypeExpr) -> Result<ResolvedArrayType>, type_annotation: Option<TypeExpr>, annotation_span: Option<ExprSpan>, ) -> Self
Creates a bundle from the parsed array annotation inputs.
type_annotation is the syntax written after : (or None for an unannotated literal),
annotation_span covers : type_expr, and resolve_array_type resolves the annotation
against the parser’s configured type resolver on demand.
§Examples
use cel_parser::{ExprSpan, TypeExpr};
use cel_parser::parser_context::AnnotatedArray;
use proc_macro2::Span;
fn ignore(_: &TypeExpr) -> cel_parser::Result<cel_parser::ResolvedArrayType> {
unreachable!("this example only bundles parsed inputs")
}
let span = ExprSpan {
start: Span::call_site(),
end: Span::call_site(),
};
let mut resolve = ignore;
let annotation = AnnotatedArray::new(
&mut resolve,
Some(TypeExpr::Array {
element: Box::new(TypeExpr::Named {
name: "i32".to_string(),
args: Vec::new(),
span,
}),
span,
}),
Some(span),
);
assert!(annotation.annotation_span().is_some());Sourcepub fn type_annotation(&self) -> Option<&TypeExpr>
pub fn type_annotation(&self) -> Option<&TypeExpr>
Returns the unresolved annotation syntax, or None for an unannotated array literal.
§Examples
use cel_parser::{ExprSpan, TypeExpr};
use cel_parser::parser_context::AnnotatedArray;
use proc_macro2::Span;
fn ignore(_: &TypeExpr) -> cel_parser::Result<cel_parser::ResolvedArrayType> {
unreachable!("this example only reads the stored annotation")
}
let span = ExprSpan {
start: Span::call_site(),
end: Span::call_site(),
};
let mut resolve = ignore;
let annotation = AnnotatedArray::new(
&mut resolve,
Some(TypeExpr::Array {
element: Box::new(TypeExpr::Named {
name: "i32".to_string(),
args: Vec::new(),
span,
}),
span,
}),
Some(span),
);
match annotation.type_annotation() {
Some(TypeExpr::Array { element, .. }) => assert!(matches!(
element.as_ref(),
TypeExpr::Named { name, .. } if name == "i32"
)),
other => panic!("expected [i32], got {other:?}"),
}Sourcepub fn annotation_span(&self) -> Option<ExprSpan>
pub fn annotation_span(&self) -> Option<ExprSpan>
Returns the span covering : type_expr, or None for an unannotated array literal.
§Examples
use cel_parser::ExprSpan;
use cel_parser::parser_context::AnnotatedArray;
use proc_macro2::Span;
fn ignore(_: &cel_parser::TypeExpr) -> cel_parser::Result<cel_parser::ResolvedArrayType> {
unreachable!("this example only reads the stored span")
}
fn ignore_none(
_: &cel_parser::TypeExpr,
) -> cel_parser::Result<cel_parser::ResolvedArrayType> {
unreachable!("this example only checks the None case")
}
let span = ExprSpan {
start: Span::call_site(),
end: Span::call_site(),
};
let mut resolve = ignore;
let annotation = AnnotatedArray::new(
&mut resolve,
None,
Some(span),
);
assert!(annotation.annotation_span().is_some());
let mut without_span = ignore_none;
assert!(
AnnotatedArray::new(&mut without_span, None, None)
.annotation_span()
.is_none()
);Sourcepub fn resolve_element_type(&mut self) -> Result<Option<ValueType>>
pub fn resolve_element_type(&mut self) -> Result<Option<ValueType>>
Resolves the declared array element metadata when a type ascription is present.
- Postcondition: returns
Ok(None)exactly whentype_annotationisNone.
§Errors
Returns Err if the annotation names an unknown type, does not name a complete array
type, or has an unrepresentable canonical layout.
§Examples
use cel_parser::{ExprSpan, ResolvedArrayType, TypeExpr};
use cel_parser::parser_context::AnnotatedArray;
use cel_runtime::ValueType;
use proc_macro2::Span;
fn resolve_i32(_: &TypeExpr) -> cel_parser::Result<ResolvedArrayType> {
Ok(ResolvedArrayType::from_element_type(
ValueType::leaf::<i32>(),
))
}
let span = ExprSpan {
start: Span::call_site(),
end: Span::call_site(),
};
let mut resolve = resolve_i32;
let mut annotation = AnnotatedArray::new(
&mut resolve,
Some(TypeExpr::Array {
element: Box::new(TypeExpr::Named {
name: "i32".to_string(),
args: Vec::new(),
span,
}),
span,
}),
Some(span),
);
let element_type = annotation.resolve_element_type().unwrap().unwrap();
assert_eq!(element_type.type_name(), "i32");Sourcepub fn into_parts(self) -> (Option<TypeExpr>, Option<ExprSpan>)
pub fn into_parts(self) -> (Option<TypeExpr>, Option<ExprSpan>)
Returns the parsed syntax-level annotation inputs unchanged.
§Examples
use cel_parser::{ExprSpan, TypeExpr};
use cel_parser::parser_context::AnnotatedArray;
use proc_macro2::Span;
fn ignore(_: &TypeExpr) -> cel_parser::Result<cel_parser::ResolvedArrayType> {
unreachable!("this example only unpacks stored parts")
}
let span = ExprSpan {
start: Span::call_site(),
end: Span::call_site(),
};
let mut resolve = ignore;
let annotation = AnnotatedArray::new(
&mut resolve,
Some(TypeExpr::Array {
element: Box::new(TypeExpr::Named {
name: "i32".to_string(),
args: Vec::new(),
span,
}),
span,
}),
Some(span),
);
let (type_annotation, annotation_span) = annotation.into_parts();
assert!(annotation_span.is_some());
match type_annotation {
Some(TypeExpr::Array { element, .. }) => assert!(matches!(
element.as_ref(),
TypeExpr::Named { name, .. } if name == "i32"
)),
other => panic!("expected [i32], got {other:?}"),
}