use crate::{AliasConfig, Filter, list_aliases};
use normalize_output::OutputFormatter;
use schemars::JsonSchema;
use serde::Serialize;
use server_less::cli;
use std::path::Path;
#[derive(Serialize, JsonSchema)]
pub struct MatchReport {
pub path: String,
pub matched: bool,
}
impl OutputFormatter for MatchReport {
fn format_text(&self) -> String {
if self.matched {
format!("{}: included", self.path)
} else {
format!("{}: excluded", self.path)
}
}
}
#[derive(Serialize, JsonSchema)]
pub struct AliasEntry {
pub name: String,
pub status: String,
pub patterns: Vec<String>,
}
#[derive(Serialize, JsonSchema)]
pub struct AliasesReport {
pub aliases: Vec<AliasEntry>,
}
impl OutputFormatter for AliasesReport {
fn format_text(&self) -> String {
let mut out = String::new();
for alias in &self.aliases {
if alias.patterns.is_empty() {
out.push_str(&format!("@{} [{}]\n", alias.name, alias.status));
} else {
out.push_str(&format!(
"@{} [{}]: {}\n",
alias.name,
alias.status,
alias.patterns.join(", ")
));
}
}
out
}
}
pub struct FilterCliService;
impl FilterCliService {
pub fn new() -> Self {
Self
}
}
impl Default for FilterCliService {
fn default() -> Self {
Self::new()
}
}
impl FilterCliService {
fn display_output<T: OutputFormatter>(&self, value: &T) -> String {
value.format_text()
}
}
#[cli(
name = "normalize-filter",
version = "0.1.0",
description = "File filtering with glob patterns and alias resolution"
)]
impl FilterCliService {
#[cli(display_with = "display_output")]
pub fn matches(
&self,
#[param(positional, help = "Path to check")] path: String,
#[param(help = "Exclude files matching pattern or alias")] exclude: Vec<String>,
#[param(help = "Include only files matching pattern or alias")] only: Vec<String>,
) -> Result<MatchReport, String> {
let config = AliasConfig::default();
let filter = Filter::new(&exclude, &only, &config, &[])?;
let matched = filter.matches(Path::new(&path));
Ok(MatchReport { path, matched })
}
#[cli(display_with = "display_output")]
pub fn aliases(&self) -> Result<AliasesReport, String> {
let config = AliasConfig::default();
let resolved = list_aliases(&config, &[]);
let aliases = resolved
.into_iter()
.map(|a| AliasEntry {
name: a.name,
status: a.status.to_string(),
patterns: a.patterns,
})
.collect();
Ok(AliasesReport { aliases })
}
}