use self::explicit_le::ExplicitVRLittleEndianDecoder;
use self::implicit_le::{ImplicitVRLittleEndianDecoder, StandardImplicitVRLittleEndianDecoder};
use byteordered::Endianness;
use dicom_core::header::{DataElementHeader, SequenceItemHeader};
use dicom_core::Tag;
use snafu::{Backtrace, Snafu};
use std::io::{self, Read};
pub mod basic;
pub mod explicit_be;
pub mod explicit_le;
pub mod implicit_le;
#[deprecated(since = "0.3.0")]
pub use dicom_core::value::deserialize as primitive_value;
#[derive(Debug, Snafu)]
#[non_exhaustive]
pub enum Error {
#[snafu(display("Failed to read the beginning (tag) of the header"))]
ReadHeaderTag {
backtrace: Option<Backtrace>,
source: io::Error,
},
#[snafu(display("Failed to read the item header"))]
ReadItemHeader {
backtrace: Backtrace,
source: io::Error,
},
#[snafu(display("Failed to read the header's item length field"))]
ReadItemLength {
backtrace: Backtrace,
source: io::Error,
},
#[snafu(display("Failed to read the header's tag field"))]
ReadTag {
backtrace: Backtrace,
source: io::Error,
},
#[snafu(display("Failed to read the header's reserved bytes"))]
ReadReserved {
backtrace: Backtrace,
source: io::Error,
},
#[snafu(display("Failed to read the header's element length field"))]
ReadLength {
backtrace: Backtrace,
source: io::Error,
},
#[snafu(display("Failed to read the header's value representation"))]
ReadVr {
backtrace: Backtrace,
source: io::Error,
},
#[snafu(display("Bad sequence item header"))]
BadSequenceHeader {
source: dicom_core::header::SequenceItemHeaderError,
},
}
pub type Result<T> = std::result::Result<T, Error>;
pub fn default_reader() -> StandardImplicitVRLittleEndianDecoder {
ImplicitVRLittleEndianDecoder::default()
}
pub fn file_header_decoder() -> ExplicitVRLittleEndianDecoder {
ExplicitVRLittleEndianDecoder::default()
}
pub trait BasicDecode {
fn endianness(&self) -> Endianness;
fn decode_us<S>(&self, source: S) -> std::io::Result<u16>
where
S: Read;
fn decode_ul<S>(&self, source: S) -> std::io::Result<u32>
where
S: Read;
fn decode_uv<S>(&self, source: S) -> std::io::Result<u64>
where
S: Read;
fn decode_ss<S>(&self, source: S) -> std::io::Result<i16>
where
S: Read;
fn decode_sl<S>(&self, source: S) -> std::io::Result<i32>
where
S: Read;
fn decode_sv<S>(&self, source: S) -> std::io::Result<i64>
where
S: Read;
fn decode_fl<S>(&self, source: S) -> std::io::Result<f32>
where
S: Read;
fn decode_fd<S>(&self, source: S) -> std::io::Result<f64>
where
S: Read;
fn decode_tag<S>(&self, mut source: S) -> std::io::Result<Tag>
where
S: Read,
{
let g = self.decode_us(&mut source)?;
let e = self.decode_us(source)?;
Ok(Tag(g, e))
}
}
impl<T: ?Sized> BasicDecode for Box<T>
where
T: BasicDecode,
{
fn endianness(&self) -> Endianness {
self.as_ref().endianness()
}
fn decode_us<S>(&self, source: S) -> std::io::Result<u16>
where
S: Read,
{
(**self).decode_us(source)
}
fn decode_ul<S>(&self, source: S) -> std::io::Result<u32>
where
S: Read,
{
(**self).decode_ul(source)
}
fn decode_uv<S>(&self, source: S) -> std::io::Result<u64>
where
S: Read,
{
(**self).decode_uv(source)
}
fn decode_ss<S>(&self, source: S) -> std::io::Result<i16>
where
S: Read,
{
(**self).decode_ss(source)
}
fn decode_sl<S>(&self, source: S) -> std::io::Result<i32>
where
S: Read,
{
(**self).decode_sl(source)
}
fn decode_sv<S>(&self, source: S) -> std::io::Result<i64>
where
S: Read,
{
(**self).decode_sv(source)
}
fn decode_fl<S>(&self, source: S) -> std::io::Result<f32>
where
S: Read,
{
(**self).decode_fl(source)
}
fn decode_fd<S>(&self, source: S) -> std::io::Result<f64>
where
S: Read,
{
(**self).decode_fd(source)
}
fn decode_tag<S>(&self, source: S) -> std::io::Result<Tag>
where
S: Read,
{
(**self).decode_tag(source)
}
}
impl<'a, T: ?Sized> BasicDecode for &'a T
where
T: BasicDecode,
{
fn endianness(&self) -> Endianness {
(*self).endianness()
}
fn decode_us<S>(&self, source: S) -> std::io::Result<u16>
where
S: Read,
{
(**self).decode_us(source)
}
fn decode_ul<S>(&self, source: S) -> std::io::Result<u32>
where
S: Read,
{
(**self).decode_ul(source)
}
fn decode_uv<S>(&self, source: S) -> std::io::Result<u64>
where
S: Read,
{
(**self).decode_uv(source)
}
fn decode_ss<S>(&self, source: S) -> std::io::Result<i16>
where
S: Read,
{
(**self).decode_ss(source)
}
fn decode_sl<S>(&self, source: S) -> std::io::Result<i32>
where
S: Read,
{
(**self).decode_sl(source)
}
fn decode_sv<S>(&self, source: S) -> std::io::Result<i64>
where
S: Read,
{
(**self).decode_sv(source)
}
fn decode_fl<S>(&self, source: S) -> std::io::Result<f32>
where
S: Read,
{
(**self).decode_fl(source)
}
fn decode_fd<S>(&self, source: S) -> std::io::Result<f64>
where
S: Read,
{
(**self).decode_fd(source)
}
fn decode_tag<S>(&self, source: S) -> std::io::Result<Tag>
where
S: Read,
{
(**self).decode_tag(source)
}
}
pub trait Decode {
fn decode_header<S>(&self, source: &mut S) -> Result<(DataElementHeader, usize)>
where
S: ?Sized + Read;
fn decode_item_header<S>(&self, source: &mut S) -> Result<SequenceItemHeader>
where
S: ?Sized + Read;
fn decode_tag<S>(&self, source: &mut S) -> Result<Tag>
where
S: ?Sized + Read;
}
impl<T: ?Sized> Decode for Box<T>
where
T: Decode,
{
fn decode_header<S>(&self, source: &mut S) -> Result<(DataElementHeader, usize)>
where
S: ?Sized + Read,
{
(**self).decode_header(source)
}
fn decode_item_header<S>(&self, source: &mut S) -> Result<SequenceItemHeader>
where
S: ?Sized + Read,
{
(**self).decode_item_header(source)
}
fn decode_tag<S>(&self, source: &mut S) -> Result<Tag>
where
S: ?Sized + Read,
{
(**self).decode_tag(source)
}
}
impl<'a, T: ?Sized> Decode for &'a T
where
T: Decode,
{
fn decode_header<S>(&self, source: &mut S) -> Result<(DataElementHeader, usize)>
where
S: ?Sized + Read,
{
(**self).decode_header(source)
}
fn decode_item_header<S>(&self, source: &mut S) -> Result<SequenceItemHeader>
where
S: ?Sized + Read,
{
(**self).decode_item_header(source)
}
fn decode_tag<S>(&self, source: &mut S) -> Result<Tag>
where
S: ?Sized + Read,
{
(**self).decode_tag(source)
}
}
pub trait DecodeFrom<S: ?Sized + Read> {
fn decode_header(&self, source: &mut S) -> Result<(DataElementHeader, usize)>;
fn decode_item_header(&self, source: &mut S) -> Result<SequenceItemHeader>;
fn decode_tag(&self, source: &mut S) -> Result<Tag>;
}
impl<S: ?Sized, T: ?Sized> DecodeFrom<S> for &T
where
S: Read,
T: DecodeFrom<S>,
{
fn decode_header(&self, source: &mut S) -> Result<(DataElementHeader, usize)> {
(**self).decode_header(source)
}
fn decode_item_header(&self, source: &mut S) -> Result<SequenceItemHeader> {
(**self).decode_item_header(source)
}
fn decode_tag(&self, source: &mut S) -> Result<Tag> {
(**self).decode_tag(source)
}
}
impl<S: ?Sized, T: ?Sized> DecodeFrom<S> for Box<T>
where
S: Read,
T: DecodeFrom<S>,
{
fn decode_header(&self, source: &mut S) -> Result<(DataElementHeader, usize)> {
(**self).decode_header(source)
}
fn decode_item_header(&self, source: &mut S) -> Result<SequenceItemHeader> {
(**self).decode_item_header(source)
}
fn decode_tag(&self, source: &mut S) -> Result<Tag> {
(**self).decode_tag(source)
}
}
#[cfg(test)]
mod tests {
use super::*;
fn is_decode_from<T: DecodeFrom<dyn Read>>(_decoder: &T) {}
#[allow(unused)]
fn boxed_decoder_from_is_decoder_from<T>(decoder: T)
where
T: DecodeFrom<dyn Read>,
{
is_decode_from(&decoder);
let boxed = Box::new(decoder);
is_decode_from(&boxed);
let erased = boxed as Box<dyn DecodeFrom<dyn Read>>;
is_decode_from(&erased);
}
}