diff --git a/CHANGELOG.md b/CHANGELOG.md index d5e639dd5..535402116 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -98,6 +98,7 @@ hdhomerun: - A new filter field `caption` has been added. This field is used to bypass the `title/name` issue. If `caption` is provided, its value is read from `title` if available, otherwise from `name`. When setting `caption`, both `title` and `name` are updated.” +- Counter has now an attribute padding. Which fills the number like 001. # 2.2.5 (2025-03-27) - fixed web ui playlist regexp search diff --git a/src/model/mapping.rs b/src/model/mapping.rs index 9dce5c502..b3c619e3b 100644 --- a/src/model/mapping.rs +++ b/src/model/mapping.rs @@ -88,6 +88,8 @@ pub struct MappingCounterDefinition { pub modifier: CounterModifier, #[serde(default)] pub value: u32, + #[serde(default)] + pub padding: u8, } #[derive(Debug, Clone)] @@ -97,6 +99,7 @@ pub struct MappingCounter { pub concat: String, pub modifier: CounterModifier, pub value: Arc, + pub padding: u8, } #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Sequence, PartialEq, Eq)] @@ -458,6 +461,7 @@ impl Mapping { concat: def.concat.clone(), modifier: def.modifier.clone(), value: Arc::new(AtomicU32::new(def.value)), + padding: def.padding, }); } Err(e) => return Err(info_err!(e.to_string())) diff --git a/src/processing/processor/playlist.rs b/src/processing/processor/playlist.rs index fbea41d93..66583f8af 100644 --- a/src/processing/processor/playlist.rs +++ b/src/processing/processor/playlist.rs @@ -275,19 +275,23 @@ fn map_playlist_counter(target: &ConfigTarget, playlist: &mut [PlaylistGroup]) { for channel in &mut plg.channels { let provider = ValueProvider { pli: channel }; if counter.filter.filter(&provider, &mut mock_processor) { - let cntval = counter.value.load(core::sync::atomic::Ordering::SeqCst); - let new_value = if counter.modifier == CounterModifier::Assign { + let cntval = counter.value.fetch_add(1, core::sync::atomic::Ordering::SeqCst); + let padded_cntval = if counter.padding > 0 { + format!("{:0width$}", cntval, width = counter.padding as usize) + } else { cntval.to_string() + }; + let new_value = if counter.modifier == CounterModifier::Assign { + padded_cntval } else { let value = channel.header.get_field(&counter.field).map_or_else(String::new, |field_value| field_value.to_string()); if counter.modifier == CounterModifier::Suffix { - format!("{value}{}{cntval}", counter.concat) + format!("{value}{}{padded_cntval}", counter.concat) } else { - format!("{cntval}{}{value}", counter.concat) + format!("{padded_cntval}{}{value}", counter.concat) } }; channel.header.set_field(&counter.field, new_value.as_str()); - counter.value.fetch_add(1, core::sync::atomic::Ordering::SeqCst); } } }