diff --git a/src/pbxproj/object/collection.rs b/src/pbxproj/object/collection.rs index c881a04..ec13925 100644 --- a/src/pbxproj/object/collection.rs +++ b/src/pbxproj/object/collection.rs @@ -1,5 +1,9 @@ -use super::PBXObject; -use std::{cell::RefCell, collections::HashMap, rc::Weak}; +use super::{PBXObject, PBXTarget, XCRemoteSwiftPackageReference}; +use std::{ + cell::RefCell, + collections::HashMap, + rc::{Rc, Weak}, +}; /// An alias for weak reference of [`PBXObjectCollection`] pub type WeakPBXObjectCollection = Weak>; @@ -8,7 +12,12 @@ pub type WeakPBXObjectCollection = Weak>; #[derive(Default, Debug, derive_new::new, derive_deref_rs::Deref)] pub struct PBXObjectCollection(pub(crate) HashMap); +/// TODO: make collections a HashSet of PBXObject with identifier included? impl PBXObjectCollection { + pub(crate) fn set_inner(&mut self, map: HashMap) { + self.0 = map; + } + /// Add new object. same as insert but it auto create id and returns it pub fn push>(&mut self, object: O) -> String { let id = uuid::Uuid::new_v4().to_string(); @@ -16,54 +25,58 @@ impl PBXObjectCollection { id } - pub(crate) fn set_inner(&mut self, map: HashMap) { - self.0 = map; + /// Get PBXTarget by reference + pub fn get_target<'a>(&'a self, reference: &str) -> Option>> { + self.get(reference)?.as_pbx_target().map(|r| r.clone()) } - // /// Get PBXTarget by the target name - // pub fn get_target_by_name<'a>( - // &'a self, - // target_name: &'a str, - // ) -> Option<(&'a String, Ref<'a, PBXObject>)> { - // self.0 - // .iter() - // .find(|(_, &o)| { - // let target = match *o.borrow() { - // PBXObject::PBXAggregateTarget(ref v) => &v.inner, - // PBXObject::PBXLegacyTarget(ref v) => &v.inner, - // PBXObject::PBXNativeTarget(ref v) => &v.inner, - // _ => return false, - // }; - // if let Some(name) = target.name.as_ref() { - // name == target_name - // } else { - // false - // } - // }) - // .map(|(key, o)| (key, o.borrow())) - // } + /// Get XCRemoteSwiftPackageReference from a vec of references + pub fn get_packages_from_references<'a>( + &'a self, + references: &Vec, + ) -> Vec<(String, Rc>)> { + references + .iter() + .map(|id| { + let package = self.get(id)?.as_xc_remote_swift_package_reference()?; + Some((id.clone(), package.clone())) + }) + .flatten() + .collect() + } - // /// Get PBXTarget by reference - // pub fn get_target(&self, reference: &str) -> Option<&PBXObject> { - // if let Some(object) = self.get(reference) { - // if object.borrow().is_pbx_target() { - // return Some(Rc::downgrade(object)); - // } - // None - // } else { - // None - // } - // } + /// Get PBXTarget from a vec of references + pub fn get_targets_from_references<'a>( + &'a self, + references: &Vec, + ) -> Vec<(String, Rc>)> { + references + .iter() + .map(|id| { + let target = self.get_target(id)?; + Some((id.clone(), target.clone())) + }) + .flatten() + .collect() + } - // /// Get mutable PBXTarget by reference - // pub fn get_target_mut(&mut self, reference: &str) -> Option<&mut PBXObject> { - // if let Some(object) = self.get_mut(reference) { - // if object.is_pbx_target() { - // return Some(object); - // } - // None - // } else { - // None - // } - // } + /// Get PBXTarget by the target name + pub fn get_target_by_name<'a>( + &'a self, + target_name: &'a str, + ) -> Option<(String, Rc>)> { + self.iter() + .find(|(_, o)| { + if let Some(target) = o.as_pbx_target() { + if let Some(name) = target.borrow().name.as_ref() { + name == target_name + } else { + false + } + } else { + false + } + }) + .map(|(key, o)| (key.clone(), o.as_pbx_target().unwrap().clone())) + } } diff --git a/src/pbxproj/object/project.rs b/src/pbxproj/object/project.rs index ce44d76..98b9b96 100644 --- a/src/pbxproj/object/project.rs +++ b/src/pbxproj/object/project.rs @@ -46,41 +46,25 @@ pub struct PBXProject { impl PBXProject { /// Get packages that the project uses #[must_use] - pub fn packages<'a>(&self) -> Option>>> { + pub fn packages<'a>( + &self, + ) -> Option>)>> { let package_references = self.package_references.as_ref()?; let objects = self.objects.upgrade()?; let objects = objects.borrow(); - let mut packages = vec![]; - - for id in package_references.iter() { - if let Some(object) = objects - .get(id) - .map(|o| o.as_xc_remote_swift_package_reference()) - .flatten() - { - packages.push(object.clone()) - } - } - - Some(packages) + Some(objects.get_packages_from_references(package_references)) } /// Get targets for given reference #[must_use] - pub fn targets(&self) -> Vec>> { - let objects = if let Some(objects) = self.objects.upgrade() { - objects + pub fn targets(&self) -> Vec<(String, Rc>)> { + let target_references = self.target_references; + if let Some(objects) = self.objects.upgrade() { + let objects = objects.borrow(); + objects.get_targets_from_references(&target_references) } else { - return vec![]; - }; - let objects = objects.borrow(); - let mut targets = vec![]; - for id in self.target_references.iter() { - if let Some(traget) = objects.get(id).map(|v| v.as_pbx_target()).flatten() { - targets.push(traget.clone()) - } + vec![] } - targets } /// Returns the attributes of a given target.