From 42b3cfa31fad9fb8bcf6c86adcfb0d39f3f0f245 Mon Sep 17 00:00:00 2001 From: Samir Talwar Date: Tue, 20 Feb 2024 11:32:09 +0100 Subject: [PATCH] Rename and extend `ValidateError`. (#102) We now need to conduct I/O during `parse_configuration`, which means the current `ValidateError` isn't quite enough. I've renamed it to `ParseError` (to complement `parse_configuration`), and added a few extra cases. 1. `ParseError`, which denotes the file path and position where parsing failed. 2. `ValidateError`, as before, but including the file path, wrapping the vector in `InvalidNodes` so we can implement `Display`. 3. `IoError`, for when we fail to read a file. 4. `Other`, because I can't think of everything. --- rust-connector-sdk/src/connector.rs | 88 ++++++++++++++++++--- rust-connector-sdk/src/connector/example.rs | 2 +- 2 files changed, 80 insertions(+), 10 deletions(-) diff --git a/rust-connector-sdk/src/connector.rs b/rust-connector-sdk/src/connector.rs index 0c4488c9..457c1ddf 100644 --- a/rust-connector-sdk/src/connector.rs +++ b/rust-connector-sdk/src/connector.rs @@ -1,4 +1,6 @@ -use std::{error::Error, path::Path}; +use std::error::Error; +use std::fmt::Display; +use std::path::{Path, PathBuf}; use async_trait::async_trait; use ndc_client::models; @@ -12,19 +14,78 @@ pub mod example; /// Errors which occur when trying to validate connector /// configuration. /// -/// See [`Connector::validate_raw_configuration`]. +/// See [`Connector::parse_configuration`]. #[derive(Debug, Error)] -pub enum ValidateError { - #[error("error validating configuration: {0:?}")] - ValidateError(Vec), +pub enum ParseError { + #[error("error parsing configuration: {0}")] + ParseError(LocatedError), + #[error("error validating configuration: {0}")] + ValidateError(InvalidNodes), + #[error("error processing configuration: {0}")] + IoError(#[from] std::io::Error), + #[error("error processing configuration: {0}")] + Other(#[from] Box), } -#[derive(Debug, Clone, Serialize)] -pub struct InvalidRange { - pub path: Vec, +/// An error associated with the position of a single character in a text file. +#[derive(Debug, Clone)] +pub struct LocatedError { + pub file_path: PathBuf, + pub line: usize, + pub column: usize, + pub message: String, +} + +impl Display for LocatedError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{0}:{1}:{2}: {3}", + self.file_path.display(), + self.line, + self.column, + self.message + ) + } +} + +/// An error associated with a node in a graph structure. +#[derive(Debug, Clone)] +pub struct InvalidNode { + pub file_path: PathBuf, + pub node_path: Vec, pub message: String, } +impl Display for InvalidNode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}, at ", self.file_path.display())?; + for segment in &self.node_path { + write!(f, ".{}", segment)?; + } + write!(f, ": {}", self.message)?; + Ok(()) + } +} + +/// A set of invalid nodes. +#[derive(Debug, Clone)] +pub struct InvalidNodes(pub Vec); + +impl Display for InvalidNodes { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut iterator = self.0.iter(); + if let Some(first) = iterator.next() { + first.fmt(f)?; + } + for next in iterator { + write!(f, ", {next}")?; + } + Ok(()) + } +} + +/// A segment in a node path, used with [InvalidNode]. #[derive(Debug, Clone, Serialize)] #[serde(untagged)] pub enum KeyOrIndex { @@ -32,6 +93,15 @@ pub enum KeyOrIndex { Index(u32), } +impl Display for KeyOrIndex { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Key(key) => write!(f, "[{key:?}]"), + Self::Index(index) => write!(f, "[{index}]"), + } + } +} + /// Errors which occur when trying to initialize connector /// state. /// @@ -200,7 +270,7 @@ pub trait Connector { /// returning a configuration error or a validated [`Connector::Configuration`]. async fn parse_configuration( configuration_dir: impl AsRef + Send, - ) -> Result; + ) -> Result; /// Initialize the connector's in-memory state. /// diff --git a/rust-connector-sdk/src/connector/example.rs b/rust-connector-sdk/src/connector/example.rs index 0a19db29..d55f23af 100644 --- a/rust-connector-sdk/src/connector/example.rs +++ b/rust-connector-sdk/src/connector/example.rs @@ -16,7 +16,7 @@ impl Connector for Example { async fn parse_configuration( _configuration_dir: impl AsRef + Send, - ) -> Result { + ) -> Result { Ok(()) }