From a9bb49c7d685dd82feaf4050f756fdf590315200 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 17 May 2026 13:56:15 +0900 Subject: fix(compile): implement abstract class traits across all types Implement BaseCommand trait and other abstract class traits across all command, downloader, io, package, and VCS driver types. Also fix trait method signatures for composer_mut and io_mut to return mutable references to Option rather than Option of mutable references. --- crates/shirabe/src/package/alias_package.rs | 52 ++++++++++++++++- .../src/package/archiver/base_exclude_filter.rs | 67 ++++++++++++++++++++++ .../package/archiver/composer_exclude_filter.rs | 6 +- .../src/package/archiver/git_exclude_filter.rs | 10 ++-- crates/shirabe/src/package/package.rs | 53 ++++++++++++++++- 5 files changed, 178 insertions(+), 10 deletions(-) (limited to 'crates/shirabe/src/package') diff --git a/crates/shirabe/src/package/alias_package.rs b/crates/shirabe/src/package/alias_package.rs index a101a1f..a427913 100644 --- a/crates/shirabe/src/package/alias_package.rs +++ b/crates/shirabe/src/package/alias_package.rs @@ -13,7 +13,11 @@ use crate::repository::repository_interface::RepositoryInterface; #[derive(Debug)] pub struct AliasPackage { - pub(crate) inner: BasePackage, + id: i64, + name: String, + pretty_name: String, + repository: Option>, + /// @var string pub(crate) version: String, /// @var string @@ -427,3 +431,49 @@ impl PackageInterface for AliasPackage { self.inner.get_repository() } } + +impl BasePackage for AliasPackage { + fn id(&self) -> i64 { + self.id + } + + fn id_mut(&mut self) -> &mut i64 { + &mut self.id + } + + fn name(&self) -> &str { + &self.name + } + + fn name_mut(&mut self) -> &mut String { + &mut self.name + } + + fn pretty_name(&self) -> &str { + &self.pretty_name + } + + fn pretty_name_mut(&mut self) -> &mut String { + &mut self.pretty_name + } + + fn repository_opt(&self) -> Option<&dyn RepositoryInterface> { + self.repository.as_ref() + } + + fn set_repository_box(&mut self, repository: Box) { + todo!() + } + + fn take_repository(&mut self) -> Option> { + todo!() + } + + fn as_any(&self) -> &dyn std::any::Any { + todo!() + } + + fn clone_box(&self) -> Box { + todo!() + } +} diff --git a/crates/shirabe/src/package/archiver/base_exclude_filter.rs b/crates/shirabe/src/package/archiver/base_exclude_filter.rs index 6522d79..c7d2557 100644 --- a/crates/shirabe/src/package/archiver/base_exclude_filter.rs +++ b/crates/shirabe/src/package/archiver/base_exclude_filter.rs @@ -3,6 +3,73 @@ use shirabe_external_packages::composer::pcre::preg::Preg; use shirabe_external_packages::symfony::component::finder::glob::Glob; +#[derive(Debug)] +pub struct BaseExcludeFilterBase { + pub source_path: String, + pub exclude_patterns: Vec<(String, bool, bool)>, +} + +impl BaseExcludeFilterBase { + pub fn new(source_path: String) -> Self { + Self { + source_path, + exclude_patterns: Vec::new(), + } + } + + pub fn parse_lines(&self, lines: Vec, line_parser: F) -> Vec<(String, bool, bool)> + where + F: Fn(&str) -> Option<(String, bool, bool)>, + { + lines + .into_iter() + .filter_map(|line| { + let line = line.trim().to_string(); + if line.is_empty() || line.starts_with('#') { + return None; + } + line_parser(&line) + }) + .collect() + } + + pub fn generate_patterns(&self, rules: Vec) -> Vec<(String, bool, bool)> { + rules + .into_iter() + .map(|rule| Self::generate_pattern(&rule)) + .collect() + } + + pub fn generate_pattern(rule: &str) -> (String, bool, bool) { + let mut negate = false; + let mut pattern = String::new(); + + let mut rule = rule.to_string(); + if !rule.is_empty() && rule.starts_with('!') { + negate = true; + rule = rule.trim_start_matches('!').to_string(); + } + + let first_slash_position = rule.find('/'); + if first_slash_position == Some(0) { + pattern = "^/".to_string(); + } else if first_slash_position.is_none() || first_slash_position == Some(rule.len() - 1) { + pattern = "/".to_string(); + } + + let rule = rule.trim_matches('/'); + + let glob_regex = Glob::to_regex(rule); + let rule_regex = &glob_regex[2..glob_regex.len() - 2]; + + ( + format!("{{{}{}(?=$|/)}}", pattern, rule_regex), + negate, + false, + ) + } +} + pub trait BaseExcludeFilter { fn source_path(&self) -> &str; fn exclude_patterns(&self) -> &[(String, bool, bool)]; diff --git a/crates/shirabe/src/package/archiver/composer_exclude_filter.rs b/crates/shirabe/src/package/archiver/composer_exclude_filter.rs index b9a32f4..979e67e 100644 --- a/crates/shirabe/src/package/archiver/composer_exclude_filter.rs +++ b/crates/shirabe/src/package/archiver/composer_exclude_filter.rs @@ -1,15 +1,15 @@ //! ref: composer/src/Composer/Package/Archiver/ComposerExcludeFilter.php -use super::base_exclude_filter::BaseExcludeFilter; +use super::base_exclude_filter::BaseExcludeFilterBase; #[derive(Debug)] pub struct ComposerExcludeFilter { - inner: BaseExcludeFilter, + inner: BaseExcludeFilterBase, } impl ComposerExcludeFilter { pub fn new(source_path: String, exclude_rules: Vec) -> Self { - let mut inner = BaseExcludeFilter::new(source_path); + let mut inner = BaseExcludeFilterBase::new(source_path); inner.exclude_patterns = inner.generate_patterns(exclude_rules); Self { inner } } diff --git a/crates/shirabe/src/package/archiver/git_exclude_filter.rs b/crates/shirabe/src/package/archiver/git_exclude_filter.rs index 8028c15..dddad12 100644 --- a/crates/shirabe/src/package/archiver/git_exclude_filter.rs +++ b/crates/shirabe/src/package/archiver/git_exclude_filter.rs @@ -1,16 +1,16 @@ //! ref: composer/src/Composer/Package/Archiver/GitExcludeFilter.php -use crate::package::archiver::base_exclude_filter::BaseExcludeFilter; +use crate::package::archiver::base_exclude_filter::BaseExcludeFilterBase; use shirabe_external_packages::composer::pcre::preg::Preg; use std::path::Path; pub struct GitExcludeFilter { - inner: BaseExcludeFilter, + inner: BaseExcludeFilterBase, } impl GitExcludeFilter { pub fn new(source_path: String) -> Self { - let inner = BaseExcludeFilter::new(source_path.clone()); + let inner = BaseExcludeFilterBase::new(source_path.clone()); let mut filter = Self { inner }; let gitattributes_path = format!("{}/.gitattributes", source_path); @@ -37,11 +37,11 @@ impl GitExcludeFilter { let parts = Preg::split(r"\s+", line); if parts.len() == 2 && parts[1] == "export-ignore" { - return BaseExcludeFilter::generate_pattern(&parts[0]); + return Some(BaseExcludeFilterBase::generate_pattern(&parts[0])); } if parts.len() == 2 && parts[1] == "-export-ignore" { - return BaseExcludeFilter::generate_pattern(&format!("!{}", parts[0])); + return BaseExcludeFilterBase::generate_pattern(&format!("!{}", parts[0])); } None diff --git a/crates/shirabe/src/package/package.rs b/crates/shirabe/src/package/package.rs index 81d6131..ae94a20 100644 --- a/crates/shirabe/src/package/package.rs +++ b/crates/shirabe/src/package/package.rs @@ -9,6 +9,7 @@ use shirabe_php_shim::{E_USER_DEPRECATED, PhpMixed, strpos, trigger_error}; use crate::package::base_package::BasePackage; use crate::package::link::Link; use crate::package::version::version_parser::VersionParser; +use crate::repository::repository_interface::RepositoryInterface; /// Mirror entry, e.g. `['url' => 'https://...', 'preferred' => true]`. #[derive(Debug, Clone)] @@ -20,7 +21,11 @@ pub struct Mirror { /// Core package definitions that are needed to resolve dependencies and install packages #[derive(Debug)] pub struct Package { - pub(crate) inner: BasePackage, + id: i64, + name: String, + pretty_name: String, + repository: Option>, + pub(crate) r#type: Option, pub(crate) target_dir: Option, /// `'source'` | `'dist'` | `null` @@ -523,3 +528,49 @@ impl Package { new_links } } + +impl BasePackage for Package { + fn id(&self) -> i64 { + self.id + } + + fn id_mut(&mut self) -> &mut i64 { + &mut self.id + } + + fn name(&self) -> &str { + &self.name + } + + fn name_mut(&mut self) -> &mut String { + &mut self.name + } + + fn pretty_name(&self) -> &str { + &self.pretty_name + } + + fn pretty_name_mut(&mut self) -> &mut String { + &mut self.pretty_name + } + + fn repository_opt(&self) -> Option<&dyn RepositoryInterface> { + self.repository.as_ref() + } + + fn set_repository_box(&mut self, repository: Box) { + todo!() + } + + fn take_repository(&mut self) -> Option> { + todo!() + } + + fn as_any(&self) -> &dyn std::any::Any { + todo!() + } + + fn clone_box(&self) -> Box { + todo!() + } +} -- cgit v1.3.1