use flamingo_verifier_sealed_types::{
ComparisonRole, FailureReason, ImageFailureReason, ImageRole, InputFailureReason,
ValidationTarget,
};
use thiserror::Error;
use super::RequestIntegrityError;
#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Enum)]
pub enum FlamingoMatchRejection {
MalformedInputs,
InvalidHashesJson,
ThumbnailHashMismatch,
InvalidThreshold,
InputRejected {
reason: FlamingoInputFailureReason,
image: Option<FlamingoImageRole>,
limit_bytes: Option<u64>,
},
MatchBelowThreshold {
comparison: FlamingoComparison,
},
ImageRejected {
image: FlamingoImageRole,
reason: FlamingoImageFailureReason,
target: Option<FlamingoValidationTarget>,
},
MatchingFailed {
comparison: FlamingoComparison,
},
Internal,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Enum)]
pub enum FlamingoComparison {
OrbSelfie,
OrbChallenge,
SelfieChallenge,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Enum)]
pub enum FlamingoImageRole {
OrbCredential,
LiveSelfie,
RtmsChallenge,
}
#[derive(Debug, Error, uniffi::Error)]
pub enum FlamingoError {
#[error("invalid {attribute}: {reason}")]
InvalidInput {
attribute: String,
reason: String,
kind: FlamingoInputFailureKind,
limit_bytes: Option<u64>,
},
#[error("invalid Flamingo verifier configuration: {0}")]
Configuration(String),
#[error("Flamingo request integrity failed: {0}")]
RequestIntegrity(RequestIntegrityError),
#[error("Flamingo service error ({code})")]
Service {
code: String,
allow_retry: bool,
},
#[error("Flamingo request timed out")]
Timeout,
#[error("Flamingo transport failed: {details}")]
Transport {
details: String,
},
#[error("invalid Flamingo response at {stage:?}")]
InvalidResponse {
stage: FlamingoResponseStage,
},
#[error("Flamingo attestation failed: {details}")]
Attestation {
details: String,
},
#[error("Flamingo channel failed: {details}")]
Channel {
details: String,
},
#[error("invalid Flamingo signing key")]
InvalidSigningKey,
#[error("invalid Flamingo match statement")]
StatementInvalid,
#[error("Flamingo reassignment retry exhausted")]
ReassignmentRequired,
}
impl From<FailureReason> for FlamingoMatchRejection {
fn from(value: FailureReason) -> Self {
match value {
FailureReason::MalformedInputs => Self::MalformedInputs,
FailureReason::InvalidHashesJson => Self::InvalidHashesJson,
FailureReason::ThumbnailHashMismatch => Self::ThumbnailHashMismatch,
FailureReason::InvalidThreshold => Self::InvalidThreshold,
FailureReason::InputRejected {
reason,
image,
limit_bytes,
} => Self::InputRejected {
reason: reason.into(),
image: image.map(Into::into),
limit_bytes,
},
FailureReason::Internal => Self::Internal,
FailureReason::MatchBelowThreshold(comparison) => {
Self::MatchBelowThreshold {
comparison: comparison.into(),
}
}
FailureReason::MatchingFailed(comparison) => Self::MatchingFailed {
comparison: comparison.into(),
},
FailureReason::ImageRejected {
image,
reason,
target,
} => Self::ImageRejected {
image: image.into(),
reason: reason.into(),
target: target.map(Into::into),
},
}
}
}
impl From<ComparisonRole> for FlamingoComparison {
fn from(value: ComparisonRole) -> Self {
match value {
ComparisonRole::OrbSelfie => Self::OrbSelfie,
ComparisonRole::OrbChallenge => Self::OrbChallenge,
ComparisonRole::SelfieChallenge => Self::SelfieChallenge,
}
}
}
impl From<ImageRole> for FlamingoImageRole {
fn from(value: ImageRole) -> Self {
match value {
ImageRole::OrbCredential => Self::OrbCredential,
ImageRole::LiveSelfie => Self::LiveSelfie,
ImageRole::RtmsChallenge => Self::RtmsChallenge,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Enum)]
pub enum FlamingoImageFailureReason {
InvalidImage,
TemplateFailed,
TooManyFaces,
ImageTooDark,
ImageTooBright,
IlluminationVariance,
FaceTooSmall,
FaceTooBig,
FaceResolutionTooLow,
FaceTooHigh,
FaceTooLow,
FaceTooFarLeft,
FaceTooFarRight,
HeadPoseYaw,
HeadPosePitchTooHigh,
HeadPosePitchTooLow,
HeadPoseRoll,
LowQuality,
SunglassesOcclusionDetected,
GlassesOcclusionDetected,
MaskOcclusionDetected,
OtherOcclusionDetected,
HairOcclusionDetected,
FasOcclusionDetected,
SpoofDetected,
DepthSpoofDetected,
ThermalSpoofDetected,
AgeBelowThreshold,
NoFaceDetected,
EyesClosed,
NonNeutralExpression,
LandmarksAlignment,
FaceOverexposed,
FaceUnderexposed,
SegmentationOcclusionProportion,
BrightArtifacts,
LightGuardScoreTooLow,
LowContrast,
MeshExpressionScore,
HighColorDistortion,
UnevenLighting,
BlurryFace,
NoisyThermalImage,
}
impl From<ImageFailureReason> for FlamingoImageFailureReason {
fn from(value: ImageFailureReason) -> Self {
match value {
ImageFailureReason::InvalidImage => Self::InvalidImage,
ImageFailureReason::TemplateFailed => Self::TemplateFailed,
ImageFailureReason::TooManyFaces => Self::TooManyFaces,
ImageFailureReason::ImageTooDark => Self::ImageTooDark,
ImageFailureReason::ImageTooBright => Self::ImageTooBright,
ImageFailureReason::IlluminationVariance => Self::IlluminationVariance,
ImageFailureReason::FaceTooSmall => Self::FaceTooSmall,
ImageFailureReason::FaceTooBig => Self::FaceTooBig,
ImageFailureReason::FaceResolutionTooLow => Self::FaceResolutionTooLow,
ImageFailureReason::FaceTooHigh => Self::FaceTooHigh,
ImageFailureReason::FaceTooLow => Self::FaceTooLow,
ImageFailureReason::FaceTooFarLeft => Self::FaceTooFarLeft,
ImageFailureReason::FaceTooFarRight => Self::FaceTooFarRight,
ImageFailureReason::HeadPoseYaw => Self::HeadPoseYaw,
ImageFailureReason::HeadPosePitchTooHigh => Self::HeadPosePitchTooHigh,
ImageFailureReason::HeadPosePitchTooLow => Self::HeadPosePitchTooLow,
ImageFailureReason::HeadPoseRoll => Self::HeadPoseRoll,
ImageFailureReason::LowQuality => Self::LowQuality,
ImageFailureReason::SunglassesOcclusionDetected => {
Self::SunglassesOcclusionDetected
}
ImageFailureReason::GlassesOcclusionDetected => {
Self::GlassesOcclusionDetected
}
ImageFailureReason::MaskOcclusionDetected => Self::MaskOcclusionDetected,
ImageFailureReason::OtherOcclusionDetected => Self::OtherOcclusionDetected,
ImageFailureReason::HairOcclusionDetected => Self::HairOcclusionDetected,
ImageFailureReason::FasOcclusionDetected => Self::FasOcclusionDetected,
ImageFailureReason::SpoofDetected => Self::SpoofDetected,
ImageFailureReason::DepthSpoofDetected => Self::DepthSpoofDetected,
ImageFailureReason::ThermalSpoofDetected => Self::ThermalSpoofDetected,
ImageFailureReason::AgeBelowThreshold => Self::AgeBelowThreshold,
ImageFailureReason::NoFaceDetected => Self::NoFaceDetected,
ImageFailureReason::EyesClosed => Self::EyesClosed,
ImageFailureReason::NonNeutralExpression => Self::NonNeutralExpression,
ImageFailureReason::LandmarksAlignment => Self::LandmarksAlignment,
ImageFailureReason::FaceOverexposed => Self::FaceOverexposed,
ImageFailureReason::FaceUnderexposed => Self::FaceUnderexposed,
ImageFailureReason::SegmentationOcclusionProportion => {
Self::SegmentationOcclusionProportion
}
ImageFailureReason::BrightArtifacts => Self::BrightArtifacts,
ImageFailureReason::LightGuardScoreTooLow => Self::LightGuardScoreTooLow,
ImageFailureReason::LowContrast => Self::LowContrast,
ImageFailureReason::MeshExpressionScore => Self::MeshExpressionScore,
ImageFailureReason::HighColorDistortion => Self::HighColorDistortion,
ImageFailureReason::UnevenLighting => Self::UnevenLighting,
ImageFailureReason::BlurryFace => Self::BlurryFace,
ImageFailureReason::NoisyThermalImage => Self::NoisyThermalImage,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Enum)]
pub enum FlamingoValidationTarget {
Image,
IlluminatedFrame,
UnilluminatedFrame,
LightGuardPair,
}
impl From<ValidationTarget> for FlamingoValidationTarget {
fn from(value: ValidationTarget) -> Self {
match value {
ValidationTarget::Image => Self::Image,
ValidationTarget::IlluminatedFrame => Self::IlluminatedFrame,
ValidationTarget::UnilluminatedFrame => Self::UnilluminatedFrame,
ValidationTarget::LightGuardPair => Self::LightGuardPair,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Enum)]
pub enum FlamingoInputFailureReason {
MissingImage,
MissingSource,
InvalidMatchingFrame,
EmptyImage,
ImageTooLarge,
TotalImagesTooLarge,
}
impl From<InputFailureReason> for FlamingoInputFailureReason {
fn from(value: InputFailureReason) -> Self {
match value {
InputFailureReason::MissingImage => Self::MissingImage,
InputFailureReason::MissingSource => Self::MissingSource,
InputFailureReason::InvalidMatchingFrame => Self::InvalidMatchingFrame,
InputFailureReason::EmptyImage => Self::EmptyImage,
InputFailureReason::ImageTooLarge => Self::ImageTooLarge,
InputFailureReason::TotalImagesTooLarge => Self::TotalImagesTooLarge,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Enum)]
pub enum FlamingoInputFailureKind {
Empty,
TooLarge,
TotalTooLarge,
InvalidThreshold,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Enum)]
pub enum FlamingoResponseStage {
Assignment,
HostMessage,
MatchResult,
}