fn remove(&mut self, target: &Node) -> Result<bool> {
        let target_paths = target.path_vec();
        let target_paths_len = target_paths.len();
        let node_paths = self.node.path_vec();
        let depth = node_paths.len();
        let whiteout_type = target.whiteout_type();

        // Don't continue to search if current path not matched with target path or recursive depth out of target path
        if depth >= target_paths_len || node_paths[depth - 1] != target_paths[depth - 1] {
            return Ok(false);
        }

        // Handle Opaques for root path (/)
        if whiteout_type == Some(WhiteoutType::Opaque) && depth == 1 && target_paths_len == 2 {
            self.node.overlay = Overlay::UpperOpaque;
            self.children.clear();
            return Ok(true);
        }

        let mut origin_name = target.name().to_os_string();
        if whiteout_type == Some(WhiteoutType::Removal) {
            if let Some(_origin_name) = origin_name.to_str() {
                origin_name = OsString::from(&_origin_name[OCISPEC_WHITEOUT_PREFIX.len()..]);
            }
        }

        let mut parent_name = None;
        if let Some(parent_path) = target.path.parent() {
            if let Some(file_name) = parent_path.file_name() {
                parent_name = Some(file_name);
            }
        }

        // TODO: Search child by binary search
        for idx in 0..self.children.len() {
            let child = &mut self.children[idx];

            // Handle Removals
            if depth == target_paths_len - 1
                && whiteout_type == Some(WhiteoutType::Removal)
                && origin_name == child.node.name()
            {
                // Remove the whole lower node
                self.children.remove(idx);
                return Ok(true);
            }

            // Handle Opaques
            if target_paths_len >= 2
                && depth == target_paths_len - 2
                && whiteout_type == Some(WhiteoutType::Opaque)
            {
                if let Some(parent_name) = parent_name {
                    if parent_name == child.node.name() {
                        child.node.overlay = Overlay::UpperOpaque;
                        // Remove children of the lower node
                        child.children.clear();
                        return Ok(true);
                    }
                }
            }

            if child.node.is_dir() {
                // Search the node recursively
                let found = child.remove(target)?;
                if found {
                    return Ok(true);
                }
            }
        }

        Ok(false)
    }
/// Remove node from node tree, return true if removed
Remove node from node tree, return true if removed
Remove node from node tree return true if removed
fn remove(&mut self, target: &Node) -> Result<bool> {
        let target_paths = target.path_vec();
        let target_paths_len = target_paths.len();
        let node_paths = self.node.path_vec();
        let depth = node_paths.len();
        let whiteout_type = target.whiteout_type();
        // Don't continue to search if current path not matched with target path or recursive depth out of target path
        if depth >= target_paths_len || node_paths[depth - 1] != target_paths[depth - 1] {
            return Ok(false);
        }
        // Handle Opaques for root path (/)
        if whiteout_type == Some(WhiteoutType::Opaque) && depth == 1 && target_paths_len == 2 {
            self.node.overlay = Overlay::UpperOpaque;
            self.children.clear();
            return Ok(true);
        }
        let mut origin_name = target.name().to_os_string();
        if whiteout_type == Some(WhiteoutType::Removal) {
            if let Some(_origin_name) = origin_name.to_str() {
                origin_name = OsString::from(&_origin_name[OCISPEC_WHITEOUT_PREFIX.len()..]);
            }
        }
        let mut parent_name = None;
        if let Some(parent_path) = target.path.parent() {
            if let Some(file_name) = parent_path.file_name() {
                parent_name = Some(file_name);
            }
        }
        // TODO: Search child by binary search
        for idx in 0..self.children.len() {
            let child = &mut self.children[idx];
            // Handle Removals
            if depth == target_paths_len - 1
                && whiteout_type == Some(WhiteoutType::Removal)
                && origin_name == child.node.name()
            {
                // Remove the whole lower node
                self.children.remove(idx);
                return Ok(true);
            }
            // Handle Opaques
            if target_paths_len >= 2
                && depth == target_paths_len - 2
                && whiteout_type == Some(WhiteoutType::Opaque)
            {
                if let Some(parent_name) = parent_name {
                    if parent_name == child.node.name() {
                        child.node.overlay = Overlay::UpperOpaque;
                        // Remove children of the lower node
                        child.children.clear();
                        return Ok(true);
                    }
                }
            }
            if child.node.is_dir() {
                // Search the node recursively
                let found = child.remove(target)?;
                if found {
                    return Ok(true);
                }
            }
        }
        Ok(false)
    }
fn remove ( & mut self , target : & Node ) -> Result < bool > { let target_paths = target . path_vec ( ) ; let target_paths_len = target_paths . len ( ) ; let node_paths = self . node . path_vec ( ) ; let depth = node_paths . len ( ) ; let whiteout_type = target . whiteout_type ( ) ; // Don't continue to search if current path not matched with target path or recursive depth out of target path if depth >= target_paths_len || node_paths [ depth - 1 ] != target_paths [ depth - 1 ] { return Ok ( false ) ; } // Handle Opaques for root path (/) if whiteout_type == Some ( WhiteoutType :: Opaque ) && depth == 1 && target_paths_len == 2 { self . node . overlay = Overlay :: UpperOpaque ; self . children . clear ( ) ; return Ok ( true ) ; } let mut origin_name = target . name ( ) . to_os_string ( ) ; if whiteout_type == Some ( WhiteoutType :: Removal ) { if let Some ( _origin_name ) = origin_name . to_str ( ) { origin_name = OsString :: from ( & _origin_name [ OCISPEC_WHITEOUT_PREFIX . len ( ) .. ] ) ; } } let mut parent_name = None ; if let Some ( parent_path ) = target . path . parent ( ) { if let Some ( file_name ) = parent_path . file_name ( ) { parent_name = Some ( file_name ) ; } } // TODO: Search child by binary search for idx in 0 .. self . children . len ( ) { let child = & mut self . children [ idx ] ; // Handle Removals if depth == target_paths_len - 1 && whiteout_type == Some ( WhiteoutType :: Removal ) && origin_name == child . node . name ( ) { // Remove the whole lower node self . children . remove ( idx ) ; return Ok ( true ) ; } // Handle Opaques if target_paths_len >= 2 && depth == target_paths_len - 2 && whiteout_type == Some ( WhiteoutType :: Opaque ) { if let Some ( parent_name ) = parent_name { if parent_name == child . node . name ( ) { child . node . overlay = Overlay :: UpperOpaque ; // Remove children of the lower node child . children . clear ( ) ; return Ok ( true ) ; } } } if child . node . is_dir ( ) { // Search the node recursively let found = child . remove ( target ) ? ; if found { return Ok ( true ) ; } } } Ok ( false ) }
Remove node from node tree, return true if removed
Remove node from node tree return true if removed
&mut self
target
&Node
&mut self
target
&Node