Initial upload: gitignore-gen Rust CLI tool with 100+ templates
Some checks failed
CI / build (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled

This commit is contained in:
2026-02-04 04:43:19 +00:00
parent 2d1c8fce90
commit 8a43eb81b5

View File

@@ -0,0 +1,163 @@
use serde::{Deserialize, Serialize};
use std::collections::HashSet;
use std::hash::{Hash, Hasher};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Template {
pub name: String,
pub category: Category,
pub patterns: Vec<String>,
pub description: Option<String>,
pub version: Option<String>,
pub author: Option<String>,
pub url: Option<String>,
}
impl Template {
pub fn new(name: String, category: Category, patterns: Vec<String>) -> Self {
Self {
name,
category,
patterns,
description: None,
version: None,
author: None,
url: None,
}
}
pub fn with_description(mut self, description: String) -> Self {
self.description = Some(description);
self
}
pub fn with_version(mut self, version: String) -> Self {
self.version = Some(version);
self
}
pub fn patterns_as_string(&self) -> String {
self.patterns.join("\n")
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub enum Category {
Language,
Framework,
IDE,
Editor,
BuildTool,
OS,
Database,
VersionControl,
Documentation,
Testing,
Misc,
Custom(String),
}
impl std::fmt::Display for Category {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Category::Language => write!(f, "Language"),
Category::Framework => write!(f, "Framework"),
Category::IDE => write!(f, "IDE"),
Category::Editor => write!(f, "Editor"),
Category::BuildTool => write!(f, "Build Tool"),
Category::OS => write!(f, "Operating System"),
Category::Database => write!(f, "Database"),
Category::VersionControl => write!(f, "Version Control"),
Category::Documentation => write!(f, "Documentation"),
Category::Testing => write!(f, "Testing"),
Category::Misc => write!(f, "Miscellaneous"),
Category::Custom(s) => write!(f, "{}", s),
}
}
}
#[derive(Debug, Clone)]
pub struct TemplateSet {
pub templates: Vec<Template>,
pub categories: Vec<Category>,
}
impl TemplateSet {
pub fn new() -> Self {
Self {
templates: Vec::new(),
categories: Vec::new(),
}
}
pub fn add(&mut self, template: Template) {
self.templates.push(template.clone());
if !self.categories.contains(&template.category) {
self.categories.push(template.category.clone());
}
}
pub fn get_by_name(&self, name: &str) -> Option<&Template> {
self.templates
.iter()
.find(|t| t.name.to_lowercase() == name.to_lowercase())
}
pub fn get_by_category(&self, category: &Category) -> Vec<&Template> {
self.templates
.iter()
.filter(|t| &t.category == category)
.collect()
}
pub fn search(&self, query: &str) -> Vec<&Template> {
let query = query.to_lowercase();
self.templates
.iter()
.filter(|t| {
t.name.to_lowercase().contains(&query)
|| t.category.to_string().to_lowercase().contains(&query)
|| t.description
.as_ref()
.map_or(false, |d| d.to_lowercase().contains(&query))
})
.collect()
}
pub fn len(&self) -> usize {
self.templates.len()
}
pub fn is_empty(&self) -> bool {
self.templates.is_empty()
}
}
impl Default for TemplateSet {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TemplateCollection {
pub templates: Vec<Template>,
pub last_updated: String,
pub version: String,
}
impl TemplateCollection {
pub fn new() -> Self {
Self {
templates: Vec::new(),
last_updated: chrono::Utc::now().to_rfc3339(),
version: "0.1.0".to_string(),
}
}
}
impl Default for TemplateCollection {
fn default() -> Self {
Self::new()
}
}