wsi_rs/core/registry/
registry_impl.rs1use super::*;
2
3impl<T: FormatProbe> FormatProbe for Arc<T> {
8 fn probe(&self, path: &Path) -> Result<ProbeResult, WsiError> {
9 (**self).probe(path)
10 }
11}
12
13impl<T: DatasetReader> DatasetReader for Arc<T> {
14 fn open(&self, path: &Path) -> Result<Box<dyn SlideReader>, WsiError> {
15 (**self).open(path)
16 }
17}
18
19#[derive(Default)]
22pub struct FormatRegistry {
23 backends: Vec<RegisteredBackend>,
24}
25
26impl std::fmt::Debug for FormatRegistry {
27 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28 f.debug_struct("FormatRegistry")
29 .field("backend_count", &self.backends.len())
30 .finish()
31 }
32}
33
34struct RegisteredBackend {
35 probe: Box<dyn FormatProbe>,
36 reader: Box<dyn DatasetReader>,
37}
38
39impl FormatRegistry {
40 pub fn new() -> Self {
41 Self::default()
42 }
43
44 pub fn register(
45 &mut self,
46 probe: impl FormatProbe + 'static,
47 reader: impl DatasetReader + 'static,
48 ) {
49 self.backends.push(RegisteredBackend {
50 probe: Box::new(probe),
51 reader: Box::new(reader),
52 });
53 }
54
55 pub fn builtin() -> Self {
57 let mut reg = Self::new();
58 let svcache = Arc::new(SvcacheBackend::new());
59 reg.register(svcache.clone(), svcache);
60 reg.register_native_backends();
61 reg
62 }
63
64 pub(crate) fn builtin_native() -> Self {
65 let mut reg = Self::new();
66 reg.register_native_backends();
67 reg
68 }
69
70 fn register_native_backends(&mut self) {
71 let dicom = Arc::new(DicomBackend::new());
72 self.register(dicom.clone(), dicom);
73 let mirax = Arc::new(MiraxBackend::new());
74 self.register(mirax.clone(), mirax);
75 let vms = Arc::new(HamamatsuVmsBackend::new());
76 self.register(vms.clone(), vms);
77 let vsi = Arc::new(OlympusVsiBackend::new());
78 self.register(vsi.clone(), vsi);
79 let raw_jp2k = Arc::new(RawJp2kBackend::new());
80 self.register(raw_jp2k.clone(), raw_jp2k);
81 let zeiss_zvi = Arc::new(ZeissZviBackend::new());
82 self.register(zeiss_zvi.clone(), zeiss_zvi);
83 let zeiss = Arc::new(ZeissBackend::new());
84 self.register(zeiss.clone(), zeiss);
85 let tiff = Arc::new(TiffFamilyBackend::new());
86 self.register(tiff.clone(), tiff);
87 }
88
89 pub fn detect_vendor(&self, path: &Path) -> Result<Option<ProbeResult>, WsiError> {
93 self.best_probe(path)
94 .map(|best| best.map(|(result, _)| result))
95 }
96
97 pub fn open(&self, path: &Path) -> Result<Box<dyn SlideReader>, WsiError> {
100 self.open_exact(path)
101 }
102
103 pub(crate) fn open_exact(&self, path: &Path) -> Result<Box<dyn SlideReader>, WsiError> {
104 match self.best_probe(path)? {
105 Some((_, i)) => self.backends[i].reader.open(path),
106 None => Err(WsiError::UnsupportedFormat(path.display().to_string())),
107 }
108 }
109
110 fn best_probe(&self, path: &Path) -> Result<Option<(ProbeResult, usize)>, WsiError> {
111 let mut best: Option<(ProbeResult, usize)> = None;
112 let mut first_error: Option<WsiError> = None;
113
114 for (i, backend) in self.backends.iter().enumerate() {
115 match backend.probe.probe(path) {
116 Ok(result) => {
117 if result.detected {
118 let should_replace = match best.as_ref() {
119 None => true,
120 Some((existing, _)) => {
121 existing.confidence == ProbeConfidence::Likely
122 && result.confidence == ProbeConfidence::Definite
123 }
124 };
125 if should_replace {
126 best = Some((result, i));
127 }
128 }
129 }
130 Err(err) => {
131 if first_error.is_none() {
132 first_error = Some(err);
133 }
134 }
135 }
136 }
137
138 match best {
139 Some(best) => Ok(Some(best)),
140 None => {
141 if let Some(err) = first_error {
142 Err(err)
143 } else {
144 Ok(None)
145 }
146 }
147 }
148 }
149}