use core::ops::Deref;
use crate::error::ErrorWithData;
use std::cmp::Ordering;
pub mod data;
pub mod list;
pub mod parse;
pub mod resolve;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Source {
pub data: data::Source,
pub loc: Option<parse::Location>,
}
impl Source {
pub fn new(data: data::Source) -> Self {
Self { data, loc: None }
}
pub fn location(&self) -> Option<&parse::Location> {
self.loc.as_ref()
}
pub fn with_location(self, loc: parse::Location) -> Self {
Self {
loc: Some(loc),
..self
}
}
}
impl Deref for Source {
type Target = data::Source;
fn deref(&self) -> &Self::Target {
&self.data
}
}
impl<T: Into<data::Source>> From<T> for Source {
fn from(value: T) -> Self {
Self::new(value.into())
}
}
pub type Version = String;
pub type VersionReq = String;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct VersionedSource {
pub source: Source,
pub current: Option<VersionReq>,
pub required: Option<VersionReq>,
}
impl VersionedSource {
pub fn new<T: Into<Source>>(source: T) -> Self {
Self {
source: source.into(),
current: None,
required: None,
}
}
pub fn with_current(self, current: impl Into<VersionReq>) -> Self {
Self {
current: Some(current.into()),
..self
}
}
pub fn with_required(self, required: impl Into<VersionReq>) -> Self {
Self {
required: Some(required.into()),
..self
}
}
pub fn with_location(self, loc: parse::Location) -> Self {
Self {
source: self.source.with_location(loc),
..self
}
}
}
impl PartialOrd for VersionedSource {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for VersionedSource {
fn cmp(&self, other: &Self) -> Ordering {
let source_cmp = self
.source
.data
.describe()
.cmp(&other.source.data.describe());
if source_cmp != Ordering::Equal {
return source_cmp;
}
let current_cmp = self.current.cmp(&other.current);
if current_cmp != Ordering::Equal {
return current_cmp;
}
self.required.cmp(&other.required)
}
}
pub fn print_errors(errors: Vec<ErrorWithData<VersionedSource>>) {
for (err, source) in errors.into_iter().map(ErrorWithData::split) {
match source.source.location() {
Some(loc) => println!(
"Error at `{}`:\n\t{}\n\t\t{:?}",
loc,
source.source.describe(),
miette::Report::new(err)
),
None => println!(
"Error for `{}`:\n\t{:?}",
source.source.describe(),
miette::Report::new(err)
),
}
}
}