mirror of
https://github.com/alexpasmantier/television.git
synced 2025-06-06 19:45:23 +00:00
refactor(cable): split cable related code into separate submodules
This commit is contained in:
parent
0514a914b6
commit
a6c83c3762
@ -9,7 +9,7 @@ use ratatui::style::Color;
|
|||||||
use ratatui::widgets::{Block, BorderType, Borders, ListDirection, Padding};
|
use ratatui::widgets::{Block, BorderType, Borders, ListDirection, Padding};
|
||||||
use ratatui::Terminal;
|
use ratatui::Terminal;
|
||||||
use television::action::Action;
|
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::into_ranges;
|
||||||
use television::channels::entry::{Entry, PreviewType};
|
use television::channels::entry::{Entry, PreviewType};
|
||||||
use television::channels::OnAir;
|
use television::channels::OnAir;
|
||||||
|
@ -2,11 +2,13 @@ use std::path::PathBuf;
|
|||||||
|
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use crate::channels::cable::{CableChannelPrototype, CableChannels};
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use tracing::{debug, error};
|
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
|
/// Just a proxy struct to deserialize prototypes
|
||||||
#[derive(Debug, serde::Deserialize, Default)]
|
#[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::collections::HashSet;
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
use std::process::Stdio;
|
use std::process::Stdio;
|
||||||
|
|
||||||
use anyhow::Result;
|
use preview::{parse_preview_kind, PreviewKind};
|
||||||
use regex::Regex;
|
use prototypes::{CableChannelPrototype, DEFAULT_DELIMITER};
|
||||||
use rustc_hash::{FxBuildHasher, FxHashSet};
|
use rustc_hash::{FxBuildHasher, FxHashSet};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
|
use crate::channels::entry::{Entry, PreviewCommand, PreviewType};
|
||||||
use crate::channels::OnAir;
|
use crate::channels::OnAir;
|
||||||
use crate::matcher::Matcher;
|
use crate::matcher::Matcher;
|
||||||
use crate::matcher::{config::Config, injector::Injector};
|
use crate::matcher::{config::Config, injector::Injector};
|
||||||
use crate::utils::command::shell_command;
|
use crate::utils::command::shell_command;
|
||||||
use crate::{
|
|
||||||
cable::ChannelPrototypes,
|
|
||||||
channels::entry::{Entry, PreviewCommand, PreviewType},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
pub mod preview;
|
||||||
pub enum PreviewKind {
|
pub mod prototypes;
|
||||||
Command(PreviewCommand),
|
|
||||||
Builtin(PreviewType),
|
|
||||||
None,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub struct Channel {
|
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 {
|
impl Channel {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
name: &str,
|
name: &str,
|
||||||
@ -234,94 +210,3 @@ impl OnAir for Channel {
|
|||||||
self.preview_kind != PreviewKind::None
|
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 std::collections::HashSet;
|
||||||
|
|
||||||
use crate::channels::cable::CableChannels;
|
use crate::channels::cable::prototypes::CableChannels;
|
||||||
use crate::channels::entry::{Entry, PreviewType};
|
use crate::channels::entry::{Entry, PreviewType};
|
||||||
use crate::channels::{OnAir, TelevisionChannel};
|
use crate::channels::{OnAir, TelevisionChannel};
|
||||||
use crate::matcher::{config::Config, Matcher};
|
use crate::matcher::{config::Config, Matcher};
|
||||||
|
@ -4,8 +4,13 @@ use std::path::Path;
|
|||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::channels::cable::{parse_preview_kind, CableChannels, PreviewKind};
|
use crate::channels::cable::{
|
||||||
use crate::channels::{cable::CableChannelPrototype, entry::PreviewCommand};
|
preview::parse_preview_kind, preview::PreviewKind,
|
||||||
|
prototypes::CableChannels,
|
||||||
|
};
|
||||||
|
use crate::channels::{
|
||||||
|
cable::prototypes::CableChannelPrototype, entry::PreviewCommand,
|
||||||
|
};
|
||||||
use crate::cli::args::{Cli, Command};
|
use crate::cli::args::{Cli, Command};
|
||||||
use crate::config::{KeyBindings, DEFAULT_CHANNEL};
|
use crate::config::{KeyBindings, DEFAULT_CHANNEL};
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -6,7 +6,9 @@ use std::process::exit;
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use television::cable;
|
use television::cable;
|
||||||
use television::channels::cable::{CableChannels, PreviewKind};
|
use television::channels::cable::{
|
||||||
|
preview::PreviewKind, prototypes::CableChannels,
|
||||||
|
};
|
||||||
use television::utils::clipboard::CLIPBOARD;
|
use television::utils::clipboard::CLIPBOARD;
|
||||||
use tracing::{debug, error, info};
|
use tracing::{debug, error, info};
|
||||||
|
|
||||||
@ -186,7 +188,8 @@ pub fn determine_channel(
|
|||||||
mod tests {
|
mod tests {
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use television::{
|
use television::{
|
||||||
cable::load_cable_channels, channels::cable::CableChannelPrototype,
|
cable::load_cable_channels,
|
||||||
|
channels::cable::prototypes::CableChannelPrototype,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -3,7 +3,7 @@ use std::{collections::HashSet, path::PathBuf, time::Duration};
|
|||||||
use television::{
|
use television::{
|
||||||
action::Action,
|
action::Action,
|
||||||
app::{App, AppOptions},
|
app::{App, AppOptions},
|
||||||
channels::{cable::CableChannelPrototype, TelevisionChannel},
|
channels::{cable::prototypes::CableChannelPrototype, TelevisionChannel},
|
||||||
config::default_config_from_file,
|
config::default_config_from_file,
|
||||||
};
|
};
|
||||||
use tokio::{task::JoinHandle, time::timeout};
|
use tokio::{task::JoinHandle, time::timeout};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user