use std::collections::BTreeMap;
use std::fmt;
use std::io::{Read, Seek, Write};
use crate::document::CadIr;
use crate::report::DecodeReport;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
pub trait ReadSeek: Read + Seek {}
impl<T: Read + Seek> ReadSeek for T {}
#[derive(
Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, JsonSchema,
)]
#[serde(rename_all = "snake_case")]
pub enum Confidence {
No,
Low,
Medium,
High,
}
impl fmt::Display for Confidence {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Self::No => "no",
Self::Low => "low",
Self::Medium => "medium",
Self::High => "high",
})
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct ContainerEntry {
pub name: String,
pub role: String,
pub compression: String,
pub compressed_size: u64,
pub uncompressed_size: u64,
#[serde(default)]
pub attributes: BTreeMap<String, String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct ContainerSummary {
pub format: String,
pub container_kind: String,
pub entries: Vec<ContainerEntry>,
pub notes: Vec<String>,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct DecodeOptions {
pub container_only: bool,
}
#[derive(Debug, Clone, PartialEq)]
pub struct DecodeResult {
pub ir: CadIr,
pub report: DecodeReport,
}
impl DecodeResult {
pub fn new(mut ir: CadIr, report: DecodeReport) -> Self {
ir.finalize();
Self { ir, report }
}
}
#[derive(Debug, thiserror::Error)]
pub enum CodecError {
#[error("not the expected format: {0}")]
WrongFormat(String),
#[error("malformed container: {0}")]
Malformed(String),
#[error("not implemented yet: {0}")]
NotImplemented(String),
#[error("io error: {0}")]
Io(#[from] std::io::Error),
}
pub trait Codec {
fn id(&self) -> &'static str;
fn detect(&self, prefix: &[u8]) -> Confidence;
fn inspect(&self, reader: &mut dyn ReadSeek) -> Result<ContainerSummary, CodecError>;
fn decode(
&self,
reader: &mut dyn ReadSeek,
options: &DecodeOptions,
) -> Result<DecodeResult, CodecError>;
}
pub trait Encoder {
fn id(&self) -> &'static str;
fn encode(&self, ir: &CadIr, writer: &mut dyn Write) -> Result<(), CodecError>;
}