//! ref: composer/src/Composer/Package/Dumper/ArrayDumper.php use std::any::Any; use indexmap::IndexMap; use shirabe_php_shim::PhpMixed; use crate::package::base_package::BasePackage; use crate::package::complete_package::CompletePackage; use crate::package::package_interface::PackageInterface; use crate::package::root_package::RootPackage; #[derive(Debug)] pub struct ArrayDumper; impl ArrayDumper { pub fn new() -> Self { Self } pub fn dump(&self, package: &dyn PackageInterface) -> IndexMap { let mut data: IndexMap = IndexMap::new(); data.insert( "name".to_string(), PhpMixed::String(package.get_pretty_name().to_string()), ); data.insert( "version".to_string(), PhpMixed::String(package.get_pretty_version().to_string()), ); data.insert( "version_normalized".to_string(), PhpMixed::String(package.get_version().to_string()), ); if let Some(target_dir) = package.get_target_dir() { data.insert( "target-dir".to_string(), PhpMixed::String(target_dir.to_string()), ); } if let Some(source_type) = package.get_source_type() { let mut source: IndexMap> = IndexMap::new(); source.insert( "type".to_string(), Box::new(PhpMixed::String(source_type.to_string())), ); source.insert( "url".to_string(), Box::new(PhpMixed::String( package.get_source_url().unwrap_or("").to_string(), )), ); if let Some(reference) = package.get_source_reference() { source.insert( "reference".to_string(), Box::new(PhpMixed::String(reference.to_string())), ); } if let Some(mirrors) = package.get_source_mirrors() { if !mirrors.is_empty() { source.insert( "mirrors".to_string(), Box::new(PhpMixed::Array( mirrors .into_iter() .enumerate() .map(|(i, m)| { ( i.to_string(), Box::new(PhpMixed::Array( m.into_iter().map(|(k, v)| (k, Box::new(v))).collect(), )), ) }) .collect(), )), ); } } data.insert("source".to_string(), PhpMixed::Array(source)); } if let Some(dist_type) = package.get_dist_type() { let mut dist: IndexMap> = IndexMap::new(); dist.insert( "type".to_string(), Box::new(PhpMixed::String(dist_type.to_string())), ); dist.insert( "url".to_string(), Box::new(PhpMixed::String( package.get_dist_url().unwrap_or("").to_string(), )), ); if let Some(reference) = package.get_dist_reference() { dist.insert( "reference".to_string(), Box::new(PhpMixed::String(reference.to_string())), ); } if let Some(shasum) = package.get_dist_sha1_checksum() { dist.insert( "shasum".to_string(), Box::new(PhpMixed::String(shasum.to_string())), ); } if let Some(mirrors) = package.get_dist_mirrors() { if !mirrors.is_empty() { dist.insert( "mirrors".to_string(), Box::new(PhpMixed::Array( mirrors .into_iter() .enumerate() .map(|(i, m)| { ( i.to_string(), Box::new(PhpMixed::Array( m.into_iter().map(|(k, v)| (k, Box::new(v))).collect(), )), ) }) .collect(), )), ); } } data.insert("dist".to_string(), PhpMixed::Array(dist)); } // corresponds to: foreach (BasePackage::$supportedLinkTypes as $type => $opts) { $links = $package->{'get'.ucfirst($opts['method'])}(); ... } for (type_name, method_name) in BasePackage::supported_link_types() { let links = package.get_links_by_method(&method_name); if links.is_empty() { continue; } let mut link_map: IndexMap> = IndexMap::new(); for link in &links { link_map.insert( link.get_target().to_string(), Box::new(PhpMixed::String(link.get_pretty_constraint().to_string())), ); } link_map.sort_keys(); data.insert(type_name, PhpMixed::Array(link_map)); } let suggests = package.get_suggests(); if !suggests.is_empty() { let mut sorted_suggests = suggests.clone(); sorted_suggests.sort_keys(); data.insert( "suggest".to_string(), PhpMixed::Array( sorted_suggests .into_iter() .map(|(k, v)| (k, Box::new(PhpMixed::String(v)))) .collect(), ), ); } if let Some(release_date) = package.get_release_date() { data.insert( "time".to_string(), PhpMixed::String(release_date.to_rfc3339()), ); } if package.is_default_branch() { data.insert("default-branch".to_string(), PhpMixed::Bool(true)); } // dumpValues for base package keys (corresponds to dynamic PHP dispatch) let binaries = package.get_binaries(); if !binaries.is_empty() { data.insert( "bin".to_string(), PhpMixed::List( binaries .into_iter() .map(|b| Box::new(PhpMixed::String(b))) .collect(), ), ); } if let Some(pkg_type) = package.get_type() { if !pkg_type.is_empty() { data.insert("type".to_string(), PhpMixed::String(pkg_type.to_string())); } } let extra = package.get_extra(); if !extra.is_empty() { data.insert( "extra".to_string(), PhpMixed::Array(extra.into_iter().map(|(k, v)| (k, Box::new(v))).collect()), ); } if let Some(installation_source) = package.get_installation_source() { data.insert( "installation-source".to_string(), PhpMixed::String(installation_source.to_string()), ); } let autoload = package.get_autoload(); if !autoload.is_empty() { data.insert( "autoload".to_string(), PhpMixed::Array( autoload .into_iter() .map(|(k, v)| (k, Box::new(v))) .collect(), ), ); } let dev_autoload = package.get_dev_autoload(); if !dev_autoload.is_empty() { data.insert( "autoload-dev".to_string(), PhpMixed::Array( dev_autoload .into_iter() .map(|(k, v)| (k, Box::new(v))) .collect(), ), ); } if let Some(notification_url) = package.get_notification_url() { data.insert( "notification-url".to_string(), PhpMixed::String(notification_url.to_string()), ); } let include_paths = package.get_include_paths(); if !include_paths.is_empty() { data.insert( "include-path".to_string(), PhpMixed::List( include_paths .into_iter() .map(|p| Box::new(PhpMixed::String(p))) .collect(), ), ); } let php_ext = package.get_php_ext(); if !php_ext.is_empty() { data.insert( "php-ext".to_string(), PhpMixed::Array(php_ext.into_iter().map(|(k, v)| (k, Box::new(v))).collect()), ); } if let Some(complete_pkg) = (package.as_any() as &dyn Any).downcast_ref::() { if let Some(archive_name) = complete_pkg.get_archive_name() { let entry = data .entry("archive".to_string()) .or_insert_with(|| PhpMixed::Array(IndexMap::new())); if let PhpMixed::Array(ref mut archive) = entry { archive.insert( "name".to_string(), Box::new(PhpMixed::String(archive_name.to_string())), ); } } let archive_excludes = complete_pkg.get_archive_excludes(); if !archive_excludes.is_empty() { let entry = data .entry("archive".to_string()) .or_insert_with(|| PhpMixed::Array(IndexMap::new())); if let PhpMixed::Array(ref mut archive) = entry { archive.insert( "exclude".to_string(), Box::new(PhpMixed::List( archive_excludes .into_iter() .map(|e| Box::new(PhpMixed::String(e))) .collect(), )), ); } } // dumpValues for complete package keys let scripts = complete_pkg.get_scripts(); if !scripts.is_empty() { data.insert( "scripts".to_string(), PhpMixed::Array( scripts .into_iter() .map(|(k, v)| { ( k, Box::new(PhpMixed::List( v.into_iter() .map(|s| Box::new(PhpMixed::String(s))) .collect(), )), ) }) .collect(), ), ); } let license = complete_pkg.get_license(); if !license.is_empty() { data.insert( "license".to_string(), PhpMixed::List( license .into_iter() .map(|l| Box::new(PhpMixed::String(l))) .collect(), ), ); } let authors = complete_pkg.get_authors(); if !authors.is_empty() { data.insert( "authors".to_string(), PhpMixed::List( authors .into_iter() .map(|a| { Box::new(PhpMixed::Array( a.into_iter() .map(|(k, v)| (k, Box::new(PhpMixed::String(v)))) .collect(), )) }) .collect(), ), ); } if let Some(description) = complete_pkg.get_description() { data.insert( "description".to_string(), PhpMixed::String(description.to_string()), ); } if let Some(homepage) = complete_pkg.get_homepage() { data.insert( "homepage".to_string(), PhpMixed::String(homepage.to_string()), ); } let mut keywords = complete_pkg.get_keywords(); if !keywords.is_empty() { keywords.sort(); data.insert( "keywords".to_string(), PhpMixed::List( keywords .into_iter() .map(|k| Box::new(PhpMixed::String(k))) .collect(), ), ); } let repositories = complete_pkg.get_repositories(); if !repositories.is_empty() { data.insert( "repositories".to_string(), PhpMixed::List( repositories .into_iter() .map(|r| { Box::new(PhpMixed::Array( r.into_iter().map(|(k, v)| (k, Box::new(v))).collect(), )) }) .collect(), ), ); } let support = complete_pkg.get_support(); if !support.is_empty() { data.insert( "support".to_string(), PhpMixed::Array( support .into_iter() .map(|(k, v)| (k, Box::new(PhpMixed::String(v)))) .collect(), ), ); } let funding = complete_pkg.get_funding(); if !funding.is_empty() { data.insert( "funding".to_string(), PhpMixed::List( funding .into_iter() .map(|f| { Box::new(PhpMixed::Array( f.into_iter().map(|(k, v)| (k, Box::new(v))).collect(), )) }) .collect(), ), ); } if complete_pkg.is_abandoned() { let abandoned_value = complete_pkg .get_replacement_package() .map(|r| PhpMixed::String(r.to_string())) .unwrap_or(PhpMixed::Bool(true)); data.insert("abandoned".to_string(), abandoned_value); } } if let Some(root_pkg) = (package.as_any() as &dyn Any).downcast_ref::() { let minimum_stability = root_pkg.get_minimum_stability(); if !minimum_stability.is_empty() { data.insert( "minimum-stability".to_string(), PhpMixed::String(minimum_stability.to_string()), ); } } let transport_options = package.get_transport_options(); if !transport_options.is_empty() { data.insert( "transport-options".to_string(), PhpMixed::Array( transport_options .into_iter() .map(|(k, v)| (k, Box::new(v))) .collect(), ), ); } data } }