1use super::{Config, ConfigTarget};
2use crate::{
3 Chapters, DefaultDispositions, DispositionType, Dispositions, Field, ForcedDispositions,
4 LangMetadata, NameMetadata, Stream, Streams, Target,
5};
6use std::path::Path;
7
8impl Config {
9 pub fn target<F, T>(&self, _: F, t: T) -> &<Self as Field<F>>::FieldType
15 where
16 Self: Field<F>,
17 ConfigTarget: Field<F, FieldType = Option<<Self as Field<F>>::FieldType>>,
18 T: AsRef<Path>,
19 {
20 self.targets
21 .as_ref()
22 .and_then(|map| {
23 map.get(t.as_ref())
24 .and_then(|v| <ConfigTarget as Field<F>>::field(v).as_ref())
25 })
26 .unwrap_or_else(|| <Self as Field<F>>::field(self))
27 }
28
29 pub(crate) fn stream_val<F, I, T>(
31 &self,
32 f: F,
33 target_paths: I,
34 stream: &Stream,
35 ) -> (usize, &<Self as Field<F>>::FieldType)
36 where
37 F: Copy,
38 Self: Field<F>,
39 ConfigTarget: Field<F, FieldType = Option<<Self as Field<F>>::FieldType>>,
40 I: IntoIterator<Item = T>,
41 T: AsRef<Path>,
42 {
43 if let Some(v) = self.get_targets(f, target_paths) {
44 (stream.i, v)
45 } else if let Some(v) = self.get_target(f, Target::Stream(stream.ty)) {
46 (stream.i_ty, v)
47 } else {
48 (stream.i, <Self as Field<F>>::field(self))
49 }
50 }
51
52 pub(crate) fn stream_val_dispositions<I, T>(
54 &self,
55 ty: DispositionType,
56 target_paths: I,
57 stream: &Stream,
58 ) -> (usize, &Dispositions)
59 where
60 I: IntoIterator<Item = T>,
61 T: AsRef<Path>,
62 {
63 match ty {
64 DispositionType::Default => {
65 let (i, xs) = self.stream_val(CfgDefaults, target_paths, stream);
66 (i, &xs.0)
67 }
68 DispositionType::Forced => {
69 let (i, xs) = self.stream_val(CfgForceds, target_paths, stream);
70 (i, &xs.0)
71 }
72 }
73 }
74
75 pub(crate) fn get_target<F, T>(&self, _: F, t: T) -> Option<&<Self as Field<F>>::FieldType>
76 where
77 Self: Field<F>,
78 ConfigTarget: Field<F, FieldType = Option<<Self as Field<F>>::FieldType>>,
79 T: AsRef<Path>,
80 {
81 self.targets.as_ref().and_then(|map| {
82 map.get(t.as_ref())
83 .and_then(|v| <ConfigTarget as Field<F>>::field(v).as_ref())
84 })
85 }
86
87 pub(crate) fn get_targets<F, I, T>(&self, f: F, ts: I) -> Option<&<Self as Field<F>>::FieldType>
88 where
89 F: Copy,
90 Self: Field<F>,
91 ConfigTarget: Field<F, FieldType = Option<<Self as Field<F>>::FieldType>>,
92 I: IntoIterator<Item = T>,
93 T: AsRef<Path>,
94 {
95 ts.into_iter().find_map(|t| self.get_target(f, t))
96 }
97
98 pub(crate) fn get_key(&self, target: impl AsRef<Path>) -> Option<Target> {
103 self.targets.as_ref().and_then(|map| {
104 map.get_key_value(target.as_ref())
105 .map(|(key, _)| key.clone())
106 })
107 }
108}
109
110macro_rules! fields {
111 ($type:ident, $opt_type:ident;
113 $( $field:ident, $ty:ty => $marker:ident ),* $(,)?
114 ) => {
115 $(
116 #[doc = concat!("Marker of [`Config`] fields, that stores [`", stringify!($ty), "`].")]
117 #[derive(Copy, Clone)]
118 pub struct $marker;
119
120 impl Field<$marker> for $type {
121 type FieldType = $ty;
122
123 #[inline(always)]
124 fn field(&self) -> &Self::FieldType {
125 &self.$field
126 }
127 }
128
129 impl Field<$marker> for $opt_type {
130 type FieldType = Option<$ty>;
131
132 #[inline(always)]
133 fn field(&self) -> &Self::FieldType {
134 &self.$field
135 }
136 }
137 )*
138 };
139}
140
141fields! {
142 Config, ConfigTarget;
143 streams, Streams => CfgStreams,
144 chapters, Chapters => CfgChapters,
145 defaults, DefaultDispositions => CfgDefaults,
146 forceds, ForcedDispositions => CfgForceds,
147 names, NameMetadata => CfgNames,
148 langs, LangMetadata => CfgLangs,
149}