use serde::Serialize;
use thiserror::Error as TError;
pub type Result<T> = anyhow::Result<T, UtpmError>;
use serde::ser::{SerializeStruct, Serializer};
use typst_syntax::package::PackageVersion;
#[derive(Debug, TError)]
pub enum UtpmError {
#[error("Git error: {0}")]
Git(String),
#[error("We didn't find git on your path. Try to add it.")]
GitNotFound,
#[error("Inquire error: {0}")]
Questions(#[from] inquire::InquireError),
#[error("IO error: {0}")]
IO(#[from] std::io::Error),
#[cfg(feature = "output_json")]
#[error("Can't parse to json: {0}")]
JsonParse(#[from] serde_json::Error),
#[error("Can't parse to hjson: {0}")]
#[cfg(feature = "output_hjson")]
HJsonParse(#[from] serde_hjson::Error),
#[cfg(feature = "output_yaml")]
#[error("Can't parse to yaml: {0}")]
YamlParse(#[from] serde_yaml::Error),
#[error("TOML serialization error: {0:?}")]
Serialize(#[from] toml::ser::Error),
#[error("TOML deserialization error: {0}")]
Deserialize(#[from] toml::de::Error),
#[error("TOML deserialization error: {0}")]
DeserializeMut(#[from] toml_edit::TomlError),
#[error("Ignore crate error: {0}")]
Ignore(#[from] ignore::Error),
#[error("Octocrab error: {0}")]
OctoCrab(#[from] octocrab::Error),
#[error("Unknown error: {0}")]
Unknown(String),
#[error("Couldn't find the current directory.")]
CurrentDir,
#[error("Could not determine home directory.")]
HomeDir,
#[error(
"Missing typst.toml manifest file in the current directory.\nRun 'utpm prj init' to create one."
)]
Manifest,
#[error(
"Invalid package format.\n\nAccepted formats:\n - Full: @namespace/package:1.0.0\n - Without version: @namespace/package\n - Namespace only: @namespace\n\nExample: @preview/example:1.0.0"
)]
PackageNotValid,
#[error(
"Package format error: the name or version is incorrect.\nExpected format: @namespace/package:version\nExample: @preview/example:1.0.0"
)]
PackageFormatError,
#[error("There is no files in the new package. You should change your ignored files.")]
NoFiles,
#[error("Can't find `typst.toml` file in {0}. Did you omit it in your ignored files?")]
OmitedTypstFile(String),
#[error("Can't find {0} file in {1}. Did you omit it in your ignored files?")]
OmitedEntryfile(String, String),
#[error(
"Package not found.\n\nPossible causes:\n - Package doesn't exist in your local storage\n - Package name or version is incorrect\n - Package is not published yet\n\nCheck available packages:\n - Local: utpm pkg list\n - Remote: https://typst.app/universe"
)]
PackageNotExist,
#[error("We founded content. Cancelled the operation.")]
ContentFound,
#[error("{2} Package {0} with version {1} already exist.")]
AlreadyExist(String, PackageVersion, String),
#[error("Reqwest Error: {0}")]
ReqwestError(#[from] reqwest::Error),
#[error("FromUTF8 Error: {0}")]
FromUTF8Error(#[from] std::string::FromUtf8Error),
#[error(transparent)]
Other(#[from] anyhow::Error),
}
impl Serialize for UtpmError {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut st = serializer.serialize_struct("UtpmError", 2)?;
st.serialize_field("type", self.variant_name())?;
st.serialize_field("message", &self.to_string())?;
st.end()
}
}
impl UtpmError {
fn variant_name(&self) -> &'static str {
use UtpmError::*;
match self {
Git(_) => "Git",
Questions(_) => "Questions",
IO(_) => "IO",
Serialize(_) => "Serialize",
Deserialize(_) => "Deserialize",
DeserializeMut(_) => "DeserializeMut",
Ignore(_) => "Ignore",
OctoCrab(_) => "OctoCrab",
Unknown(_) => "Unknown",
CurrentDir => "CurrentDir",
HomeDir => "HomeDir",
Manifest => "Manifest",
PackageNotValid => "PackageNotValid",
PackageNotExist => "PackageNotExist",
ContentFound => "ContentFound",
AlreadyExist(_, _, _) => "AlreadyExist",
Other(_) => "Other",
#[cfg(feature = "output_json")]
JsonParse(_) => "JSONParse",
#[cfg(feature = "output_hjson")]
HJsonParse(_) => "HJSONParse",
#[cfg(feature = "output_yaml")]
YamlParse(_) => "YamlParse",
ReqwestError(_) => "ReqwestError",
FromUTF8Error(_) => "FromUTF8Error",
GitNotFound => "GitNotFound",
PackageFormatError => "PackageFormatError",
NoFiles => "NoFiles",
OmitedTypstFile(_) => "OmitedTypstFile",
OmitedEntryfile(_, _) => "OmitedEntryfile",
}
}
}