specta_typescript/
error.rs1use core::fmt;
2use std::borrow::Cow;
3
4use specta_serde::SerdeError;
5use thiserror::Error;
6
7use specta::ImplLocation;
8
9use super::ExportPath;
10
11#[derive(Error, Debug, PartialEq)]
13pub enum NamedLocation {
14 Type,
15 Field,
16 Variant,
17}
18
19impl fmt::Display for NamedLocation {
20 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21 match self {
22 Self::Type => write!(f, "type"),
23 Self::Field => write!(f, "field"),
24 Self::Variant => write!(f, "variant"),
25 }
26 }
27}
28
29#[derive(Error, Debug)]
31#[non_exhaustive]
32pub enum ExportError {
33 #[error("Attempted to export '{0}' but Specta configuration forbids exporting BigInt types (i64, u64, i128, u128) because we don't know if your se/deserializer supports it. You can change this behavior by editing your `ExportConfiguration`!")]
34 BigIntForbidden(ExportPath),
35 #[error("Serde error: {0}")]
36 Serde(#[from] SerdeError),
37 #[error("Attempted to export '{1}' but was unable to due to {0} name '{2}' conflicting with a reserved keyword in Typescript. Try renaming it or using `#[specta(rename = \"new name\")]`")]
40 ForbiddenName(NamedLocation, ExportPath, &'static str),
41 #[error("Attempted to export '{1}' but was unable to due to {0} name '{2}' containing an invalid character")]
42 InvalidName(NamedLocation, ExportPath, String),
43 #[error("Attempted to export '{0}' with tagging but the type is not tagged.")]
44 InvalidTagging(ExportPath),
45 #[error("Attempted to export '{0}' with internal tagging but the variant is a tuple struct.")]
46 InvalidTaggedVariantContainingTupleStruct(ExportPath),
47 #[error("Unable to export type named '{0}' from locations '{:?}' '{:?}'", .1.as_str(), .2.as_str())]
48 DuplicateTypeName(Cow<'static, str>, ImplLocation, ImplLocation),
49 #[error("IO error: {0}")]
50 Io(#[from] std::io::Error),
51 #[error("fmt error: {0}")]
52 Fmt(#[from] std::fmt::Error),
53 #[error("Failed to export '{0}' due to error: {1}")]
54 Other(ExportPath, String),
55}
56
57impl PartialEq for ExportError {
59 fn eq(&self, other: &Self) -> bool {
60 match (self, other) {
61 (Self::BigIntForbidden(l0), Self::BigIntForbidden(r0)) => l0 == r0,
62 (Self::Serde(l0), Self::Serde(r0)) => l0 == r0,
63 (Self::ForbiddenName(l0, l1, l2), Self::ForbiddenName(r0, r1, r2)) => {
65 l0 == r0 && l1 == r1 && l2 == r2
66 }
67 (Self::InvalidName(l0, l1, l2), Self::InvalidName(r0, r1, r2)) => {
68 l0 == r0 && l1 == r1 && l2 == r2
69 }
70 (Self::InvalidTagging(l0), Self::InvalidTagging(r0)) => l0 == r0,
71 (
72 Self::InvalidTaggedVariantContainingTupleStruct(l0),
73 Self::InvalidTaggedVariantContainingTupleStruct(r0),
74 ) => l0 == r0,
75 (Self::DuplicateTypeName(l0, l1, l2), Self::DuplicateTypeName(r0, r1, r2)) => {
76 l0 == r0 && l1 == r1 && l2 == r2
77 }
78 (Self::Io(l0), Self::Io(r0)) => l0.to_string() == r0.to_string(), (Self::Other(l0, l1), Self::Other(r0, r1)) => l0 == r0 && l1 == r1,
80 _ => false,
81 }
82 }
83}