Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions cedar-policy-core/src/parser/err.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,6 @@ pub(crate) type RawErrorRecovery<'a> = lalr::ErrorRecovery<RawLocation, RawToken
type OwnedRawParseError = lalr::ParseError<RawLocation, String, RawUserError>;

/// Errors that can occur when parsing Cedar policies or expressions.
//
// CAUTION: this type is publicly exported in `cedar-policy`.
// Don't make fields `pub`, don't make breaking changes, and use caution when
// adding public methods.
#[derive(Clone, Debug, Diagnostic, Error, PartialEq, Eq)]
pub enum ParseError {
/// Error from the text -> CST parser
Expand Down Expand Up @@ -696,10 +692,6 @@ pub fn expected_to_string(expected: &[String], config: &ExpectedTokenConfig) ->

/// Represents one or more [`ParseError`]s encountered when parsing a policy or
/// template.
//
// CAUTION: this type is publicly exported in `cedar-policy`.
// Don't make fields `pub`, don't make breaking changes, and use caution when
// adding public methods.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ParseErrors(NonEmpty<ParseError>);

Expand Down
3 changes: 3 additions & 0 deletions cedar-policy/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
the rich data provided by `miette::Diagnostic`, for instance `.help()` and
`labels()`. Callers can continue using the same behavior by calling
`.iter().map(ToString::to_string)`. (#882, resolving #543)
- Removed `ParseError::primary_source_span`. Callers should use the location
information provided by `miette::Diagnostic` via `.labels()` and
`.source_code()` instead. (#908)
- Removed `Display` impl for `EntityId` in favor of explicit `.escaped()` and
`.as_ref()` for escaped and unescaped representations (respectively) of the
`EntityId`; see note there (#921, resolving #884)
Expand Down
11 changes: 8 additions & 3 deletions cedar-policy/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1613,7 +1613,9 @@ impl FromStr for EntityNamespace {
type Err = ParseErrors;

fn from_str(namespace_str: &str) -> Result<Self, Self::Err> {
ast::Name::from_normalized_str(namespace_str).map(EntityNamespace)
ast::Name::from_normalized_str(namespace_str)
.map(EntityNamespace)
.map_err(Into::into)
}
}

Expand Down Expand Up @@ -2777,7 +2779,8 @@ impl LosslessPolicy {
match self {
Self::Est(est) => Ok(est.clone()),
Self::Text { text, slots } => {
let est = parser::parse_policy_or_template_to_est(text)?;
let est =
parser::parse_policy_or_template_to_est(text).map_err(ParseErrors::from)?;
if slots.is_empty() {
Ok(est)
} else {
Expand Down Expand Up @@ -2907,7 +2910,9 @@ impl FromStr for Expression {

/// create an Expression using Cedar syntax
fn from_str(expression: &str) -> Result<Self, Self::Err> {
ast::Expr::from_str(expression).map(Expression)
ast::Expr::from_str(expression)
.map(Expression)
.map_err(Into::into)
}
}

Expand Down
32 changes: 31 additions & 1 deletion cedar-policy/src/api/err.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ pub use cedar_policy_core::evaluator::{evaluation_errors, EvaluationError};
pub use cedar_policy_core::extensions::{
extension_function_lookup_errors, ExtensionFunctionLookupError,
};
pub use cedar_policy_core::parser::err::{ParseError, ParseErrors};
use cedar_policy_core::{ast, authorizer, est};
pub use cedar_policy_validator::human_schema::{schema_warnings, SchemaWarning};
pub use cedar_policy_validator::{schema_errors, SchemaError};
use miette::Diagnostic;
use ref_cast::RefCast;
use smol_str::SmolStr;
use thiserror::Error;

Expand Down Expand Up @@ -731,6 +731,36 @@ impl From<ast::UnexpectedSlotError> for PolicySetError {
}
}

/// Represents one or more [`ParseError`]s encountered when parsing a policy or
/// expression.
/// By default, the `Diagnostic` and `Error` implementations will only print the
/// first error. If you want to see all errors, use `.iter()` or `.into_iter()`.
#[derive(Debug, Diagnostic, Error)]
#[error(transparent)]
#[diagnostic(transparent)]
pub struct ParseErrors(#[from] cedar_policy_core::parser::err::ParseErrors);

impl ParseErrors {
/// Get every [`ParseError`] associated with this [`ParseErrors`] object.
/// The returned iterator is guaranteed to be nonempty.
pub fn iter(&self) -> impl Iterator<Item = &ParseError> {
self.0.iter().map(ParseError::ref_cast)
}
}

/// Errors that can occur when parsing policies or expressions.
/// Marked as `non_exhaustive` to support adding additional error information
/// in the future without a major version bump.
Comment on lines +752 to +753
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we technically need non_exhaustive for that, since the fields are already private, but it doesn't hurt

#[derive(Debug, Diagnostic, Error, RefCast)]
#[repr(transparent)]
#[error(transparent)]
#[diagnostic(transparent)]
#[non_exhaustive]
pub struct ParseError {
#[from]
inner: cedar_policy_core::parser::err::ParseError,
}

/// Errors that can happen when getting the JSON representation of a policy
#[derive(Debug, Diagnostic, Error)]
pub enum PolicyToJsonError {
Expand Down
8 changes: 6 additions & 2 deletions cedar-policy/src/api/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,9 @@ impl FromStr for EntityTypeName {
type Err = ParseErrors;

fn from_str(namespace_type_str: &str) -> Result<Self, Self::Err> {
ast::Name::from_normalized_str(namespace_type_str).map(Self::new)
ast::Name::from_normalized_str(namespace_type_str)
.map(Self::new)
.map_err(Into::into)
}
}

Expand Down Expand Up @@ -279,7 +281,9 @@ impl FromStr for EntityUid {
/// If you have separate components of an [`EntityUid`], use [`EntityUid::from_type_name_and_id`]
fn from_str(uid_str: &str) -> Result<Self, Self::Err> {
// INVARIANT there is no way to write down the unspecified entity
ast::EntityUID::from_normalized_str(uid_str).map(Self::new)
ast::EntityUID::from_normalized_str(uid_str)
.map(Self::new)
.map_err(Into::into)
}
}

Expand Down