Skip to content

Commit cafa19c

Browse files
committed
[encoding] Refactor EncodeTo
- do not impl EncodeTo for all Encode, - instead use wrapper type EncoderFor
1 parent 5486de4 commit cafa19c

File tree

4 files changed

+110
-37
lines changed

4 files changed

+110
-37
lines changed

encoding/src/encode/mod.rs

Lines changed: 84 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -363,33 +363,99 @@ pub trait EncodeTo<W: ?Sized> {
363363
W: Write;
364364
}
365365

366-
impl<T, W: ?Sized> EncodeTo<W> for T
366+
impl<T, W: ?Sized> EncodeTo<W> for &T
367367
where
368-
T: Encode,
369-
W: Write,
368+
T: EncodeTo<W>,
370369
{
371-
fn encode_tag(&self, to: &mut W, tag: Tag) -> Result<()> {
372-
Encode::encode_tag(self, to, tag)
370+
fn encode_tag(&self, to: &mut W, tag: Tag) -> Result<()>
371+
where
372+
W: Write
373+
{
374+
(**self).encode_tag(to, tag)
373375
}
374376

375-
fn encode_element_header(&self, to: &mut W, de: DataElementHeader) -> Result<usize> {
376-
Encode::encode_element_header(self, to, de)
377+
fn encode_element_header(&self, to: &mut W, de: DataElementHeader) -> Result<usize>
378+
where
379+
W: Write
380+
{
381+
(**self).encode_element_header(to, de)
377382
}
378383

379-
fn encode_item_header(&self, to: &mut W, len: u32) -> Result<()> {
380-
Encode::encode_item_header(self, to, len)
384+
fn encode_item_header(&self, to: &mut W, len: u32) -> Result<()>
385+
where
386+
W: Write
387+
{
388+
(**self).encode_item_header(to, len)
381389
}
382390

383-
fn encode_item_delimiter(&self, to: &mut W) -> Result<()> {
384-
Encode::encode_item_delimiter(self, to)
391+
fn encode_item_delimiter(&self, to: &mut W) -> Result<()>
392+
where
393+
W: Write
394+
{
395+
(**self).encode_item_delimiter(to)
385396
}
386397

387-
fn encode_sequence_delimiter(&self, to: &mut W) -> Result<()> {
388-
Encode::encode_sequence_delimiter(self, to)
398+
fn encode_sequence_delimiter(&self, to: &mut W) -> Result<()>
399+
where
400+
W: Write
401+
{
402+
(**self).encode_sequence_delimiter(to)
389403
}
390404

391-
fn encode_primitive(&self, to: &mut W, value: &PrimitiveValue) -> Result<usize> {
392-
Encode::encode_primitive(self, to, value)
405+
/// Encode and write a primitive DICOM value to the given destination.
406+
fn encode_primitive(&self, to: &mut W, value: &PrimitiveValue) -> Result<usize>
407+
where
408+
W: Write
409+
{
410+
(**self).encode_primitive(to, value)
411+
}
412+
}
413+
414+
impl<T: ?Sized, W: ?Sized> EncodeTo<W> for Box<T>
415+
where
416+
T: EncodeTo<W>,
417+
{
418+
fn encode_tag(&self, to: &mut W, tag: Tag) -> Result<()>
419+
where
420+
W: Write
421+
{
422+
(**self).encode_tag(to, tag)
423+
}
424+
425+
fn encode_element_header(&self, to: &mut W, de: DataElementHeader) -> Result<usize>
426+
where
427+
W: Write
428+
{
429+
(**self).encode_element_header(to, de)
430+
}
431+
432+
fn encode_item_header(&self, to: &mut W, len: u32) -> Result<()>
433+
where
434+
W: Write
435+
{
436+
(**self).encode_item_header(to, len)
437+
}
438+
439+
fn encode_item_delimiter(&self, to: &mut W) -> Result<()>
440+
where
441+
W: Write
442+
{
443+
(**self).encode_item_delimiter(to)
444+
}
445+
446+
fn encode_sequence_delimiter(&self, to: &mut W) -> Result<()>
447+
where
448+
W: Write
449+
{
450+
(**self).encode_sequence_delimiter(to)
451+
}
452+
453+
/// Encode and write a primitive DICOM value to the given destination.
454+
fn encode_primitive(&self, to: &mut W, value: &PrimitiveValue) -> Result<usize>
455+
where
456+
W: Write
457+
{
458+
(**self).encode_primitive(to, value)
393459
}
394460
}
395461

@@ -536,11 +602,12 @@ mod tests {
536602
fn boxed_encode_is_encode<T>(encoder: T)
537603
where
538604
T: Encode,
605+
T: Copy,
539606
{
540607
is_encode(&encoder);
541-
is_encode_to::<dyn Write, _>(&encoder);
608+
is_encode_to::<dyn Write, _>(&EncoderFor::new(encoder));
542609
let boxed = Box::new(encoder);
543610
is_encode(&boxed);
544-
is_encode_to::<dyn Write, _>(&boxed);
611+
is_encode_to::<dyn Write, _>(&EncoderFor::new(boxed));
545612
}
546613
}

encoding/src/transfer_syntax/mod.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub mod implicit_le;
1515

1616
use crate::decode::basic::BasicDecoder;
1717
use crate::decode::DecodeFrom;
18-
use crate::encode::EncodeTo;
18+
use crate::encode::{EncodeTo, EncoderFor};
1919
use std::io::{Read, Write};
2020

2121
pub use byteordered::Endianness;
@@ -24,7 +24,7 @@ pub use byteordered::Endianness;
2424
pub type DynDecoder<S> = Box<dyn DecodeFrom<S>>;
2525

2626
/// An encoder with its type erased.
27-
pub type DynEncoder<W> = Box<dyn EncodeTo<W>>;
27+
pub type DynEncoder<'w, W> = Box<dyn EncodeTo<W> + 'w>;
2828

2929
/// A DICOM transfer syntax specifier. The data RW adapter `A` specifies
3030
/// custom codec capabilities when required.
@@ -309,29 +309,32 @@ impl<A> TransferSyntax<A> {
309309
/// Retrieve the appropriate data element encoder for this transfer syntax.
310310
/// Can yield none if encoding is not supported. The resulting encoder does not
311311
/// consider pixel data encapsulation or data set compression rules.
312-
pub fn encoder<'w>(&self) -> Option<DynEncoder<dyn Write + 'w>> {
312+
pub fn encoder<'w>(&self) -> Option<DynEncoder<'w, dyn Write + 'w>> {
313313
self.encoder_for()
314314
}
315315

316316
/// Retrieve the appropriate data element encoder for this transfer syntax
317317
/// and the given writer type (this method is not object safe).
318318
/// Can yield none if encoding is not supported. The resulting encoder does not
319319
/// consider pixel data encapsulation or data set compression rules.
320-
pub fn encoder_for<W>(&self) -> Option<DynEncoder<W>>
320+
pub fn encoder_for<'w, W: 'w>(&self) -> Option<DynEncoder<'w, W>>
321321
where
322322
Self: Sized,
323323
W: ?Sized + Write,
324324
{
325325
match (self.byte_order, self.explicit_vr) {
326326
(Endianness::Little, false) => Some(Box::new(
327-
implicit_le::ImplicitVRLittleEndianEncoder::default(),
328-
)),
327+
EncoderFor::new(
328+
implicit_le::ImplicitVRLittleEndianEncoder::default())),
329+
),
329330
(Endianness::Little, true) => Some(Box::new(
330-
explicit_le::ExplicitVRLittleEndianEncoder::default(),
331-
)),
332-
(Endianness::Big, true) => {
333-
Some(Box::new(explicit_be::ExplicitVRBigEndianEncoder::default()))
334-
}
331+
EncoderFor::new(
332+
explicit_le::ExplicitVRLittleEndianEncoder::default())),
333+
),
334+
(Endianness::Big, true) => Some(Box::new(
335+
EncoderFor::new(
336+
explicit_be::ExplicitVRBigEndianEncoder::default())),
337+
),
335338
_ => None,
336339
}
337340
}

parser/src/dataset/write.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ use crate::dataset::*;
33
use crate::error::{DataSetSyntaxError, Error, Result};
44
use crate::stateful::encode::StatefulEncoder;
55
use dicom_core::{DataElementHeader, Length, VR};
6-
use dicom_encoding::encode::{Encode, EncodeTo};
6+
use dicom_encoding::encode::EncodeTo;
77
use dicom_encoding::text::{SpecificCharacterSet, TextCodec};
88
use dicom_encoding::TransferSyntax;
9+
use dicom_encoding::transfer_syntax::DynEncoder;
910
use std::io::Write;
1011

1112
/// A writer-specific token representing a sequence or item start.
@@ -28,11 +29,11 @@ pub struct DataSetWriter<W, E, T> {
2829
last_de: Option<DataElementHeader>,
2930
}
3031

31-
impl<W> DataSetWriter<W, Box<dyn EncodeTo<W>>, Box<dyn TextCodec>>
32+
impl<'w, W: 'w> DataSetWriter<W, DynEncoder<'w, W>, Box<dyn TextCodec>>
3233
where
3334
W: Write,
3435
{
35-
pub fn with_ts_cs(to: W, ts: TransferSyntax, cs: SpecificCharacterSet) -> Result<Self> {
36+
pub fn with_ts_cs(to: W, ts: &TransferSyntax, cs: SpecificCharacterSet) -> Result<Self> {
3637
let encoder = ts
3738
.encoder_for()
3839
.ok_or_else(|| Error::UnsupportedTransferSyntax)?;
@@ -54,10 +55,11 @@ impl<W, E, T> DataSetWriter<W, E, T> {
5455
impl<W, E, T> DataSetWriter<W, E, T>
5556
where
5657
W: Write,
57-
E: Encode,
58+
E: EncodeTo<W>,
5859
T: TextCodec,
5960
{
6061
/// Feed the given sequence of tokens which are part of the same data set.
62+
#[inline]
6163
pub fn write_sequence<I>(&mut self, tokens: I) -> Result<()>
6264
where
6365
I: IntoIterator<Item = DataToken>,
@@ -70,7 +72,6 @@ where
7072
}
7173

7274
/// Feed the given data set token for writing the data set.
73-
#[inline]
7475
pub fn write(&mut self, token: DataToken) -> Result<()> {
7576
// adjust the logic of sequence printing:
7677
// explicit length sequences or items should not print
@@ -161,14 +162,15 @@ mod tests {
161162
Tag, VR,
162163
};
163164
use dicom_encoding::text::DefaultCharacterSetCodec;
165+
use dicom_encoding::encode::EncoderFor;
164166
use dicom_encoding::transfer_syntax::explicit_le::ExplicitVRLittleEndianEncoder;
165167

166168
fn validate_dataset_writer<I>(tokens: I, ground_truth: &[u8])
167169
where
168170
I: IntoIterator<Item = DataToken>,
169171
{
170172
let mut raw_out: Vec<u8> = vec![];
171-
let encoder = ExplicitVRLittleEndianEncoder::default();
173+
let encoder = EncoderFor::new(ExplicitVRLittleEndianEncoder::default());
172174
let text = DefaultCharacterSetCodec::default();
173175
let mut dset_writer = DataSetWriter::new(&mut raw_out, encoder, text);
174176

parser/src/stateful/encode.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use dicom_encoding::{
99
text::{DefaultCharacterSetCodec, SpecificCharacterSet, TextCodec},
1010
TransferSyntax,
1111
};
12+
use dicom_encoding::transfer_syntax::DynEncoder;
1213
use std::io::Write;
1314

1415
/// Also called a printer, this encoder type provides a stateful mid-level
@@ -23,9 +24,9 @@ pub struct StatefulEncoder<W, E, T> {
2324
bytes_written: u64,
2425
}
2526

26-
pub type DynStatefulEncoder<'s> =
27-
StatefulEncoder<Box<dyn Write + 's>, Box<dyn EncodeTo<dyn Write + 's>>, Box<dyn TextCodec>>;
28-
27+
pub type DynStatefulEncoder<'w> =
28+
StatefulEncoder< Box<dyn Write + 'w>, DynEncoder<'w, dyn Write>, Box<dyn TextCodec>>;
29+
2930
impl<W, E, T> StatefulEncoder<W, E, T> {
3031
pub fn new(to: W, encoder: E, text: T) -> Self {
3132
StatefulEncoder {

0 commit comments

Comments
 (0)