mirror of
https://github.com/alexpasmantier/television.git
synced 2025-06-03 01:50:12 +00:00
refactor(cable): split cable related code into separate submodules (#486)
This refactors `television/channels/cable.rs` into two additional submodules: - `television/channels/cable/preview.rs` - `television/channels/cable/prototypes.rs`
This commit is contained in:
parent
0514a914b6
commit
4385317e06
@ -9,7 +9,7 @@ use ratatui::style::Color;
|
||||
use ratatui::widgets::{Block, BorderType, Borders, ListDirection, Padding};
|
||||
use ratatui::Terminal;
|
||||
use television::action::Action;
|
||||
use television::channels::cable::CableChannelPrototype;
|
||||
use television::channels::cable::prototypes::CableChannelPrototype;
|
||||
use television::channels::entry::into_ranges;
|
||||
use television::channels::entry::{Entry, PreviewType};
|
||||
use television::channels::OnAir;
|
||||
|
@ -2,11 +2,13 @@ use std::path::PathBuf;
|
||||
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use crate::channels::cable::{CableChannelPrototype, CableChannels};
|
||||
use anyhow::Result;
|
||||
use tracing::{debug, error};
|
||||
|
||||
use crate::config::get_config_dir;
|
||||
use crate::{
|
||||
channels::cable::prototypes::{CableChannelPrototype, CableChannels},
|
||||
config::get_config_dir,
|
||||
};
|
||||
|
||||
/// Just a proxy struct to deserialize prototypes
|
||||
#[derive(Debug, serde::Deserialize, Default)]
|
||||
|
@ -1,33 +1,20 @@
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::{
|
||||
fmt::{self, Display, Formatter},
|
||||
ops::Deref,
|
||||
};
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::process::Stdio;
|
||||
|
||||
use anyhow::Result;
|
||||
use regex::Regex;
|
||||
use preview::{parse_preview_kind, PreviewKind};
|
||||
use prototypes::{CableChannelPrototype, DEFAULT_DELIMITER};
|
||||
use rustc_hash::{FxBuildHasher, FxHashSet};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::channels::entry::{Entry, PreviewCommand, PreviewType};
|
||||
use crate::channels::OnAir;
|
||||
use crate::matcher::Matcher;
|
||||
use crate::matcher::{config::Config, injector::Injector};
|
||||
use crate::utils::command::shell_command;
|
||||
use crate::{
|
||||
cable::ChannelPrototypes,
|
||||
channels::entry::{Entry, PreviewCommand, PreviewType},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum PreviewKind {
|
||||
Command(PreviewCommand),
|
||||
Builtin(PreviewType),
|
||||
None,
|
||||
}
|
||||
pub mod preview;
|
||||
pub mod prototypes;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct Channel {
|
||||
@ -69,17 +56,6 @@ impl From<CableChannelPrototype> for Channel {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_preview_kind(command: &PreviewCommand) -> Result<PreviewKind> {
|
||||
debug!("Parsing preview kind for command: {:?}", command);
|
||||
let re = Regex::new(r"^\:(\w+)\:$").unwrap();
|
||||
if let Some(captures) = re.captures(&command.command) {
|
||||
let preview_type = PreviewType::try_from(&captures[1])?;
|
||||
Ok(PreviewKind::Builtin(preview_type))
|
||||
} else {
|
||||
Ok(PreviewKind::Command(command.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
impl Channel {
|
||||
pub fn new(
|
||||
name: &str,
|
||||
@ -234,94 +210,3 @@ impl OnAir for Channel {
|
||||
self.preview_kind != PreviewKind::None
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, PartialEq)]
|
||||
pub struct CableChannelPrototype {
|
||||
pub name: String,
|
||||
pub source_command: String,
|
||||
#[serde(default)]
|
||||
pub interactive: bool,
|
||||
pub preview_command: Option<String>,
|
||||
#[serde(default = "default_delimiter")]
|
||||
pub preview_delimiter: Option<String>,
|
||||
}
|
||||
|
||||
impl CableChannelPrototype {
|
||||
pub fn new(
|
||||
name: &str,
|
||||
source_command: &str,
|
||||
interactive: bool,
|
||||
preview_command: Option<String>,
|
||||
preview_delimiter: Option<String>,
|
||||
) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
source_command: source_command.to_string(),
|
||||
interactive,
|
||||
preview_command,
|
||||
preview_delimiter,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const DEFAULT_PROTOTYPE_NAME: &str = "files";
|
||||
const DEFAULT_SOURCE_COMMAND: &str = "fd -t f";
|
||||
const DEFAULT_PREVIEW_COMMAND: &str = ":files:";
|
||||
|
||||
impl Default for CableChannelPrototype {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: DEFAULT_PROTOTYPE_NAME.to_string(),
|
||||
source_command: DEFAULT_SOURCE_COMMAND.to_string(),
|
||||
interactive: false,
|
||||
preview_command: Some(DEFAULT_PREVIEW_COMMAND.to_string()),
|
||||
preview_delimiter: Some(DEFAULT_DELIMITER.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub const DEFAULT_DELIMITER: &str = " ";
|
||||
|
||||
#[allow(clippy::unnecessary_wraps)]
|
||||
fn default_delimiter() -> Option<String> {
|
||||
Some(DEFAULT_DELIMITER.to_string())
|
||||
}
|
||||
|
||||
impl Display for CableChannelPrototype {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.name)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize)]
|
||||
pub struct CableChannels(pub FxHashMap<String, CableChannelPrototype>);
|
||||
|
||||
impl Deref for CableChannels {
|
||||
type Target = FxHashMap<String, CableChannelPrototype>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
const DEFAULT_CABLE_CHANNELS_FILE: &str =
|
||||
include_str!("../../cable/unix-channels.toml");
|
||||
#[cfg(not(unix))]
|
||||
const DEFAULT_CABLE_CHANNELS_FILE: &str =
|
||||
include_str!("../../cable/windows-channels.toml");
|
||||
|
||||
impl Default for CableChannels {
|
||||
/// Fallback to the default cable channels specification (the template file
|
||||
/// included in the repo).
|
||||
fn default() -> Self {
|
||||
let pts =
|
||||
toml::from_str::<ChannelPrototypes>(DEFAULT_CABLE_CHANNELS_FILE)
|
||||
.expect("Unable to parse default cable channels");
|
||||
let mut channels = FxHashMap::default();
|
||||
for prototype in pts.prototypes {
|
||||
channels.insert(prototype.name.clone(), prototype);
|
||||
}
|
||||
CableChannels(channels)
|
||||
}
|
||||
}
|
||||
|
34
television/channels/cable/preview.rs
Normal file
34
television/channels/cable/preview.rs
Normal file
@ -0,0 +1,34 @@
|
||||
use anyhow::Result;
|
||||
use regex::Regex;
|
||||
use tracing::debug;
|
||||
|
||||
use crate::channels::entry::{PreviewCommand, PreviewType};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum PreviewKind {
|
||||
Command(PreviewCommand),
|
||||
Builtin(PreviewType),
|
||||
None,
|
||||
}
|
||||
|
||||
/// Parses the preview command to determine if it is a built-in (i.e. ":files:") or custom command.
|
||||
///
|
||||
/// # Example:
|
||||
/// ```
|
||||
/// use television::channels::entry::{PreviewCommand, PreviewType};
|
||||
/// use television::channels::cable::preview::{parse_preview_kind, PreviewKind};
|
||||
///
|
||||
/// let command = PreviewCommand::new("cat {0}", ":");
|
||||
/// let preview_kind = parse_preview_kind(&command).unwrap();
|
||||
/// assert_eq!(preview_kind, PreviewKind::Command(command));
|
||||
/// ```
|
||||
pub fn parse_preview_kind(command: &PreviewCommand) -> Result<PreviewKind> {
|
||||
debug!("Parsing preview kind for command: {:?}", command);
|
||||
let re = Regex::new(r"^\:(\w+)\:$").unwrap();
|
||||
if let Some(captures) = re.captures(&command.command) {
|
||||
let preview_type = PreviewType::try_from(&captures[1])?;
|
||||
Ok(PreviewKind::Builtin(preview_type))
|
||||
} else {
|
||||
Ok(PreviewKind::Command(command.clone()))
|
||||
}
|
||||
}
|
98
television/channels/cable/prototypes.rs
Normal file
98
television/channels/cable/prototypes.rs
Normal file
@ -0,0 +1,98 @@
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::{
|
||||
fmt::{self, Display, Formatter},
|
||||
ops::Deref,
|
||||
};
|
||||
|
||||
use crate::cable::ChannelPrototypes;
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, PartialEq)]
|
||||
pub struct CableChannelPrototype {
|
||||
pub name: String,
|
||||
pub source_command: String,
|
||||
#[serde(default)]
|
||||
pub interactive: bool,
|
||||
pub preview_command: Option<String>,
|
||||
#[serde(default = "default_delimiter")]
|
||||
pub preview_delimiter: Option<String>,
|
||||
}
|
||||
|
||||
impl CableChannelPrototype {
|
||||
pub fn new(
|
||||
name: &str,
|
||||
source_command: &str,
|
||||
interactive: bool,
|
||||
preview_command: Option<String>,
|
||||
preview_delimiter: Option<String>,
|
||||
) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
source_command: source_command.to_string(),
|
||||
interactive,
|
||||
preview_command,
|
||||
preview_delimiter,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const DEFAULT_PROTOTYPE_NAME: &str = "files";
|
||||
const DEFAULT_SOURCE_COMMAND: &str = "fd -t f";
|
||||
const DEFAULT_PREVIEW_COMMAND: &str = ":files:";
|
||||
|
||||
impl Default for CableChannelPrototype {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: DEFAULT_PROTOTYPE_NAME.to_string(),
|
||||
source_command: DEFAULT_SOURCE_COMMAND.to_string(),
|
||||
interactive: false,
|
||||
preview_command: Some(DEFAULT_PREVIEW_COMMAND.to_string()),
|
||||
preview_delimiter: Some(DEFAULT_DELIMITER.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub const DEFAULT_DELIMITER: &str = " ";
|
||||
|
||||
#[allow(clippy::unnecessary_wraps)]
|
||||
fn default_delimiter() -> Option<String> {
|
||||
Some(DEFAULT_DELIMITER.to_string())
|
||||
}
|
||||
|
||||
impl Display for CableChannelPrototype {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.name)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize)]
|
||||
pub struct CableChannels(pub FxHashMap<String, CableChannelPrototype>);
|
||||
|
||||
impl Deref for CableChannels {
|
||||
type Target = FxHashMap<String, CableChannelPrototype>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
const DEFAULT_CABLE_CHANNELS_FILE: &str =
|
||||
include_str!("../../../cable/unix-channels.toml");
|
||||
#[cfg(not(unix))]
|
||||
const DEFAULT_CABLE_CHANNELS_FILE: &str =
|
||||
include_str!("../../cable/windows-channels.toml");
|
||||
|
||||
impl Default for CableChannels {
|
||||
/// Fallback to the default cable channels specification (the template file
|
||||
/// included in the repo).
|
||||
fn default() -> Self {
|
||||
let pts =
|
||||
toml::from_str::<ChannelPrototypes>(DEFAULT_CABLE_CHANNELS_FILE)
|
||||
.expect("Unable to parse default cable channels");
|
||||
let mut channels = FxHashMap::default();
|
||||
for prototype in pts.prototypes {
|
||||
channels.insert(prototype.name.clone(), prototype);
|
||||
}
|
||||
CableChannels(channels)
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
use crate::channels::cable::CableChannels;
|
||||
use crate::channels::cable::prototypes::CableChannels;
|
||||
use crate::channels::entry::{Entry, PreviewType};
|
||||
use crate::channels::{OnAir, TelevisionChannel};
|
||||
use crate::matcher::{config::Config, Matcher};
|
||||
|
@ -4,8 +4,13 @@ use std::path::Path;
|
||||
use anyhow::{anyhow, Result};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::channels::cable::{parse_preview_kind, CableChannels, PreviewKind};
|
||||
use crate::channels::{cable::CableChannelPrototype, entry::PreviewCommand};
|
||||
use crate::channels::cable::{
|
||||
preview::parse_preview_kind, preview::PreviewKind,
|
||||
prototypes::CableChannels,
|
||||
};
|
||||
use crate::channels::{
|
||||
cable::prototypes::CableChannelPrototype, entry::PreviewCommand,
|
||||
};
|
||||
use crate::cli::args::{Cli, Command};
|
||||
use crate::config::{KeyBindings, DEFAULT_CHANNEL};
|
||||
use crate::{
|
||||
|
@ -6,7 +6,9 @@ use std::process::exit;
|
||||
use anyhow::Result;
|
||||
use clap::Parser;
|
||||
use television::cable;
|
||||
use television::channels::cable::{CableChannels, PreviewKind};
|
||||
use television::channels::cable::{
|
||||
preview::PreviewKind, prototypes::CableChannels,
|
||||
};
|
||||
use television::utils::clipboard::CLIPBOARD;
|
||||
use tracing::{debug, error, info};
|
||||
|
||||
@ -186,7 +188,8 @@ pub fn determine_channel(
|
||||
mod tests {
|
||||
use rustc_hash::FxHashMap;
|
||||
use television::{
|
||||
cable::load_cable_channels, channels::cable::CableChannelPrototype,
|
||||
cable::load_cable_channels,
|
||||
channels::cable::prototypes::CableChannelPrototype,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
@ -3,7 +3,7 @@ use std::{collections::HashSet, path::PathBuf, time::Duration};
|
||||
use television::{
|
||||
action::Action,
|
||||
app::{App, AppOptions},
|
||||
channels::{cable::CableChannelPrototype, TelevisionChannel},
|
||||
channels::{cable::prototypes::CableChannelPrototype, TelevisionChannel},
|
||||
config::default_config_from_file,
|
||||
};
|
||||
use tokio::{task::JoinHandle, time::timeout};
|
||||
|
Loading…
x
Reference in New Issue
Block a user