1use dicom_core::{DataDictionary, Tag};
2use dicom_dictionary_std::StandardDataDictionary;
3use dicom_encoding::transfer_syntax::TransferSyntaxIndex;
4use dicom_transfer_syntax_registry::TransferSyntaxRegistry;
5
6pub use dicom_parser::dataset::read::OddLengthStrategy;
8pub use dicom_parser::stateful::decode::CharacterSetOverride;
9
10use crate::{DefaultDicomObject, ReadError};
11use std::io::Read;
12use std::path::Path;
13
14pub type Result<T, E = ReadError> = std::result::Result<T, E>;
15
16pub fn from_reader<F>(file: F) -> Result<DefaultDicomObject>
21where
22 F: Read,
23{
24 OpenFileOptions::new().from_reader(file)
25}
26
27pub fn open_file<P>(path: P) -> Result<DefaultDicomObject>
32where
33 P: AsRef<Path>,
34{
35 OpenFileOptions::new().open_file(path)
36}
37
38#[derive(Debug, Default, Clone)]
59#[non_exhaustive]
60pub struct OpenFileOptions<D = StandardDataDictionary, T = TransferSyntaxRegistry> {
61 data_dictionary: D,
62 ts_index: T,
63 read_until: Option<Tag>,
64 read_preamble: ReadPreamble,
65 odd_length: OddLengthStrategy,
66 charset_override: CharacterSetOverride,
67}
68
69impl OpenFileOptions {
70 pub fn new() -> Self {
71 OpenFileOptions::default()
72 }
73}
74
75impl<D, T> OpenFileOptions<D, T> {
76 pub fn read_until(mut self, tag: Tag) -> Self {
83 self.read_until = Some(tag);
84 self
85 }
86
87 pub fn read_all(mut self) -> Self {
91 self.read_until = None;
92 self
93 }
94
95 pub fn read_preamble(mut self, option: ReadPreamble) -> Self {
97 self.read_preamble = option;
98 self
99 }
100
101 pub fn odd_length_strategy(mut self, option: OddLengthStrategy) -> Self {
103 self.odd_length = option;
104 self
105 }
106
107 pub fn charset_override(mut self, option: CharacterSetOverride) -> Self {
109 self.charset_override = option;
110 self
111 }
112
113 pub fn transfer_syntax_index<Tr>(self, ts_index: Tr) -> OpenFileOptions<D, Tr>
115 where
116 Tr: TransferSyntaxIndex,
117 {
118 OpenFileOptions {
119 data_dictionary: self.data_dictionary,
120 read_until: self.read_until,
121 read_preamble: self.read_preamble,
122 ts_index,
123 odd_length: self.odd_length,
124 charset_override: self.charset_override,
125 }
126 }
127
128 #[deprecated(since = "0.8.1", note = "please use `transfer_syntax_index` instead")]
130 pub fn tranfer_syntax_index<Tr>(self, ts_index: Tr) -> OpenFileOptions<D, Tr>
131 where
132 Tr: TransferSyntaxIndex,
133 {
134 self.transfer_syntax_index(ts_index)
135 }
136
137 pub fn dictionary<Di>(self, dict: Di) -> OpenFileOptions<Di, T>
139 where
140 Di: DataDictionary,
141 Di: Clone,
142 {
143 OpenFileOptions {
144 data_dictionary: dict,
145 read_until: self.read_until,
146 read_preamble: self.read_preamble,
147 ts_index: self.ts_index,
148 odd_length: self.odd_length,
149 charset_override: self.charset_override,
150 }
151 }
152
153 pub fn open_file<P>(self, path: P) -> Result<DefaultDicomObject<D>>
155 where
156 P: AsRef<Path>,
157 D: DataDictionary,
158 D: Clone,
159 T: TransferSyntaxIndex,
160 {
161 DefaultDicomObject::open_file_with_all_options(
162 path,
163 self.data_dictionary,
164 self.ts_index,
165 self.read_until,
166 self.read_preamble,
167 self.odd_length,
168 self.charset_override,
169 )
170 }
171
172 pub fn from_reader<R>(self, from: R) -> Result<DefaultDicomObject<D>>
178 where
179 R: Read,
180 D: DataDictionary,
181 D: Clone,
182 T: TransferSyntaxIndex,
183 {
184 DefaultDicomObject::from_reader_with_all_options(
185 from,
186 self.data_dictionary,
187 self.ts_index,
188 self.read_until,
189 self.read_preamble,
190 self.odd_length,
191 self.charset_override,
192 )
193 }
194}
195
196#[derive(Debug, Default, Copy, Clone, Eq, Hash, PartialEq)]
199pub enum ReadPreamble {
200 #[default]
205 Auto,
206 Never,
209 Always,
212}