Skip to main content

cargo_uv/manifest/
error.rs

1use std::{
2    fmt::{self, Display, Formatter},
3    panic::Location,
4    path::PathBuf,
5};
6
7use miette::Diagnostic;
8use rusty_viking::EnumDisplay;
9
10use crate::VersionLocation;
11
12#[derive(Debug, thiserror::Error, Diagnostic)]
13pub struct CargoFileError {
14    #[source]
15    kind: CargoFileErrorKind,
16    path: PathBuf,
17    #[help("Call location: {location_called}")]
18    location_called: Location<'static>,
19}
20
21impl CargoFileError {
22    pub fn kind(&self) -> &CargoFileErrorKind {
23        &self.kind
24    }
25}
26
27impl Display for CargoFileError {
28    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
29        write!(f, "Cargo.toml: {}", self.path.display())
30    }
31}
32
33// #[allow(dead_code)]
34#[derive(Debug, thiserror::Error, miette::Diagnostic)]
35pub enum CargoFileErrorKind {
36    #[error("No root package")]
37    NoRootPackage,
38    #[error("No workspace package version")]
39    NoWorkspaceVersion,
40    #[error("No package version")]
41    NoPackageVersion,
42    #[error("No workspace or root package version is present")]
43    NoPackageOrWorkspaceVersion,
44    #[error("This package version is set by the workspace")]
45    SetByWorkspace,
46    #[error("Cargo file error with Version Location")]
47    LocationError(#[from] VersionlocationError),
48}
49
50impl CargoFileErrorKind {
51    #[track_caller]
52    pub fn to_error(self, path: impl Into<PathBuf>) -> CargoFileError {
53        CargoFileError {
54            kind: self,
55            path: path.into(),
56            location_called: *Location::caller(),
57        }
58    }
59}
60
61#[derive(Debug, thiserror::Error, miette::Diagnostic)]
62pub enum VersionLocationErrorKind {
63    #[error("Version is set by workspace.")]
64    SetByWorkspace,
65    #[error("Version not located in {0}")]
66    NotFound(VersionLocation),
67    #[error("No package defined in toml file.")]
68    PackageNotFound,
69    #[error("No workspace defined in toml file.")]
70    WorkspaceNotFound,
71    #[error("Invalid item type of {0}")]
72    ItemInvalid(ItemType),
73    #[error("Invalid semver: {0}")]
74    SemverError(semver::Error),
75}
76
77impl From<semver::Error> for VersionLocationErrorKind {
78    fn from(value: semver::Error) -> Self {
79        Self::SemverError(value)
80    }
81}
82
83impl VersionLocationErrorKind {
84    #[track_caller]
85    pub fn to_error(
86        self,
87        path: impl Into<PathBuf>,
88        context: Option<impl ToString + std::default::Default>,
89    ) -> VersionlocationError {
90        VersionlocationError {
91            kind: self,
92            path: path.into(),
93            location_called: Location::caller(),
94            context: context.unwrap_or_default().to_string(),
95        }
96    }
97}
98
99#[derive(Debug, thiserror::Error, miette::Diagnostic)]
100#[error("{context}")]
101pub struct VersionlocationError {
102    #[source]
103    kind: VersionLocationErrorKind,
104    path: PathBuf,
105    #[help("Call location: {location_called}")]
106    location_called: &'static Location<'static>,
107    context: String,
108}
109
110impl VersionlocationError {
111    pub fn new(
112        kind: VersionLocationErrorKind,
113        path: PathBuf,
114        location_called: &'static Location<'static>,
115        context: String,
116    ) -> Self {
117        Self {
118            kind,
119            path,
120            location_called,
121            context,
122        }
123    }
124
125    pub fn path(&self) -> &PathBuf {
126        &self.path
127    }
128
129    pub fn kind(&self) -> &VersionLocationErrorKind {
130        &self.kind
131    }
132}
133
134#[derive(Debug, PartialEq, Eq, Clone, Copy, EnumDisplay)]
135#[Title]
136pub enum ItemType {
137    None,
138    Value,
139    Table,
140    ArrayOfTables,
141}
142
143impl From<toml_edit::Item> for ItemType {
144    fn from(item: toml_edit::Item) -> Self {
145        match item {
146            toml_edit::Item::None => ItemType::None,
147            toml_edit::Item::Value(_) => ItemType::Value,
148            toml_edit::Item::Table(_) => ItemType::Table,
149            toml_edit::Item::ArrayOfTables(_) => ItemType::ArrayOfTables,
150        }
151    }
152}
153impl From<&toml_edit::Item> for ItemType {
154    fn from(item: &toml_edit::Item) -> Self {
155        match item {
156            toml_edit::Item::None => ItemType::None,
157            toml_edit::Item::Value(_) => ItemType::Value,
158            toml_edit::Item::Table(_) => ItemType::Table,
159            toml_edit::Item::ArrayOfTables(_) => ItemType::ArrayOfTables,
160        }
161    }
162}
163impl From<&mut toml_edit::Item> for ItemType {
164    fn from(item: &mut toml_edit::Item) -> Self {
165        match item {
166            toml_edit::Item::None => ItemType::None,
167            toml_edit::Item::Value(_) => ItemType::Value,
168            toml_edit::Item::Table(_) => ItemType::Table,
169            toml_edit::Item::ArrayOfTables(_) => ItemType::ArrayOfTables,
170        }
171    }
172}