docs(utils): add documentation for string formatting logic (#517)

This commit is contained in:
Alex Pasmantier 2025-05-20 23:24:16 +02:00 committed by GitHub
parent 6b3c4ee773
commit 7bbf538898
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 40 additions and 46 deletions

View File

@ -12,7 +12,7 @@ use crate::matcher::Matcher;
use crate::matcher::{config::Config, injector::Injector};
use crate::utils::command::shell_command;
use super::prototypes::format_prototype_string;
use crate::utils::strings::format_string;
pub struct Channel {
pub name: String,
@ -72,11 +72,8 @@ impl Channel {
let name = item.matched_string;
if let Some(cmd) = &self.preview_command {
if let Some(offset_expr) = &cmd.offset_expr {
let offset_string = format_prototype_string(
offset_expr,
&name,
&cmd.delimiter,
);
let offset_string =
format_string(offset_expr, &name, &cmd.delimiter);
let offset_str = {
offset_string
.strip_prefix('\'')

View File

@ -2,7 +2,7 @@ use std::fmt::Display;
use serde::Deserialize;
use crate::channels::{entry::Entry, prototypes::format_prototype_string};
use crate::{channels::entry::Entry, utils::strings::format_string};
#[derive(Debug, Clone, Eq, PartialEq, Hash, Default, Deserialize)]
pub struct PreviewCommand {
@ -53,7 +53,7 @@ impl PreviewCommand {
/// assert_eq!(formatted_command, "something 'a:given:entry:to:preview' 'entry' 'a'");
/// ```
pub fn format_with(&self, entry: &Entry) -> String {
format_prototype_string(&self.command, &entry.name, &self.delimiter)
format_string(&self.command, &entry.name, &self.delimiter)
}
}

View File

@ -1,4 +1,3 @@
use lazy_regex::{regex, Lazy, Regex};
use rustc_hash::FxHashMap;
use std::{
fmt::{self, Display, Formatter},
@ -93,43 +92,6 @@ impl Display for ChannelPrototype {
}
}
pub static CMD_RE: &Lazy<Regex> = regex!(r"\{(\d+)\}");
/// Formats a prototype string with the given template and source strings.
///
/// # Example
/// ```
/// use television::channels::prototypes::format_prototype_string;
///
/// let template = "cat {} {1}";
/// let source = "foo:bar:baz";
/// let delimiter = ":";
///
/// let formatted = format_prototype_string(template, source, delimiter);
/// assert_eq!(formatted, "cat 'foo:bar:baz' 'bar'");
/// ```
pub fn format_prototype_string(
template: &str,
source: &str,
delimiter: &str,
) -> String {
let parts = source.split(delimiter).collect::<Vec<&str>>();
let mut formatted_string =
template.replace("{}", format!("'{}'", source).as_str());
formatted_string = CMD_RE
.replace_all(&formatted_string, |caps: &regex::Captures| {
let index =
// these unwraps are safe because of the regex pattern
caps.get(1).unwrap().as_str().parse::<usize>().unwrap();
format!("'{}'", parts.get(index).unwrap_or(&""))
})
.to_string();
formatted_string
}
/// A neat `HashMap` of channel prototypes indexed by their name.
///
/// This is used to store cable channel prototypes throughout the application

View File

@ -1,3 +1,5 @@
use lazy_regex::{regex, Lazy, Regex};
/// Returns the index of the next character boundary in the given string.
///
/// If the given index is already a character boundary, it is returned as is.
@ -562,6 +564,39 @@ pub fn shrink_with_ellipsis(s: &str, max_length: usize) -> String {
format!("{first_half}{second_half}")
}
pub static CMD_RE: &Lazy<Regex> = regex!(r"\{(\d+)\}");
/// Formats a prototype string with the given template and source strings.
///
/// # Example
/// ```
/// use television::utils::strings::format_string;
///
/// let template = "cat {} {1}";
/// let source = "foo:bar:baz";
/// let delimiter = ":";
///
/// let formatted = format_string(template, source, delimiter);
/// assert_eq!(formatted, "cat 'foo:bar:baz' 'bar'");
/// ```
pub fn format_string(template: &str, source: &str, delimiter: &str) -> String {
let parts = source.split(delimiter).collect::<Vec<&str>>();
let mut formatted_string =
template.replace("{}", format!("'{}'", source).as_str());
formatted_string = CMD_RE
.replace_all(&formatted_string, |caps: &regex::Captures| {
let index =
// these unwraps are safe because of the regex pattern
caps.get(1).unwrap().as_str().parse::<usize>().unwrap();
format!("'{}'", parts.get(index).unwrap_or(&""))
})
.to_string();
formatted_string
}
#[cfg(test)]
mod tests {
use super::*;