use std::io;
use std::path::PathBuf;
use crate::validate::Violation;
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum TokenEnumError {
#[error("names source `{spelling}`, which is not spelled `Class.property`")]
MalformedSource {
spelling: String,
},
#[error("names class `{class}`, which the library does not declare")]
UnknownClass {
class: String,
},
#[error("names `{class}.{property}`, which the class does not declare")]
UnknownProperty {
class: String,
property: String,
},
#[error("sources `{class}.{property}`, which declares no allowedTokens")]
NoAllowedTokens {
class: String,
property: String,
},
#[error("asks for a default, but `{class}.{property}` declares no token fallback")]
NoFallback {
class: String,
property: String,
},
#[error("asks for a default of `{token}`, which is not among its allowed tokens")]
UnknownFallback {
token: String,
},
#[error("has no Rust name for token `{token}`; give one with TokenEnum::variant")]
UnnameableToken {
token: String,
},
#[error("names both `{first}` and `{second}` `{variant}`; give one a name with TokenEnum::variant")]
VariantCollision {
first: String,
second: String,
variant: String,
},
#[error("is not a Rust identifier")]
InvalidName,
#[error("takes the name of another item the generated file declares")]
ReservedName,
#[error("names library `{library}`, which this build neither generates nor declares")]
UnknownLibrary {
library: String,
},
#[error("names token `{token}` `{variant}`, which is not a Rust identifier")]
InvalidVariant {
token: String,
variant: String,
},
#[error("names a variant for token `{token}`, which is not among its allowed tokens")]
UnknownVariantToken {
token: String,
},
#[error("is declared more than once")]
Duplicate,
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
#[error("no output directory: call Builder::out_dir, or run this from a build script, which sets OUT_DIR")]
NoOutDir,
#[error(transparent)]
Core(#[from] openusd::Error),
#[error("{schema} does not compose: {diagnostic}")]
Composition {
schema: PathBuf,
diagnostic: String,
},
#[error("{schema}: no /GLOBAL prim declares customData.libraryName")]
NoLibraryName {
schema: PathBuf,
},
#[error("{origin}: {violation}")]
Definition {
origin: String,
violation: Violation,
},
#[error("token enum `{name}` {cause}")]
TokenEnum {
name: String,
cause: TokenEnumError,
},
#[error("{schema}.{field} holds a {kind} value, which the generated declaration cannot express")]
UnwritableValue {
schema: String,
field: String,
kind: &'static str,
},
#[error("generated Rust for {schema} does not parse: {cause}")]
Malformed {
schema: String,
cause: String,
},
#[error("{first} and {second} both declare libraryName `{library}`, so both would write {library}.rs")]
DuplicateLibrary {
library: String,
first: PathBuf,
second: PathBuf,
},
#[error("invalid shader definitions {path}: {cause}")]
ShaderDefs {
path: PathBuf,
cause: String,
},
#[error("invalid plugInfo {path}: {cause}")]
PlugInfo {
path: PathBuf,
cause: String,
},
#[error("{path} declares plugin `{plugin}`, which is neither a configured schema library nor a declaration family")]
UnknownPlugin {
plugin: String,
path: PathBuf,
},
#[error("declaration family `{family}` is not a valid identifier")]
InvalidDeclarationFamily {
family: String,
},
#[error("no configured plugInfo declares a plugin called `{family}`, requested as a declaration family")]
UnknownDeclarationFamily {
family: String,
},
#[error("kind `{kind}` is declared by both {first} and {second}")]
DuplicateKind {
kind: String,
first: String,
second: String,
},
#[error("metadata field `{field}` is declared by both {first} and {second}")]
DuplicateMetadataField {
field: String,
first: String,
second: String,
},
#[error("metadata fields `{first}` and `{second}` of {library} both need a method called `{method}`")]
MetadataMethodCollision {
library: String,
method: String,
first: String,
second: String,
},
#[error("cannot access {path}")]
Io {
path: PathBuf,
#[source]
source: io::Error,
},
}
impl Error {
pub(crate) fn composition(schema: &std::path::Path, stage: &openusd::usd::Stage) -> Option<Self> {
let diagnostic = stage.composition_errors().first()?.to_string();
Some(Error::Composition {
schema: schema.to_path_buf(),
diagnostic,
})
}
}
impl From<openusd::sdf::PathParseError> for Error {
fn from(source: openusd::sdf::PathParseError) -> Self {
Error::Core(source.into())
}
}
impl From<openusd::sdf::EditError> for Error {
fn from(source: openusd::sdf::EditError) -> Self {
Error::Core(source.into())
}
}
impl From<openusd::pcp::QueryError> for Error {
fn from(source: openusd::pcp::QueryError) -> Self {
Error::Core(source.into())
}
}
impl From<openusd::sdf::DataError> for Error {
fn from(source: openusd::sdf::DataError) -> Self {
Error::Core(source.into())
}
}