jimage_rs/
resource_name.rs

1use crate::error::Result;
2use crate::JImage;
3use std::borrow::Cow;
4use std::iter::FusedIterator;
5
6/// Represents the components of a resource name in a JImage file.
7#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
8pub struct ResourceName<'a> {
9    pub module: Cow<'a, str>,
10    pub parent: Cow<'a, str>,
11    pub base: Cow<'a, str>,
12    pub extension: Cow<'a, str>,
13}
14
15impl<'a> ResourceName<'a> {
16    /// Gets the full resource name as a tuple of (module, full_path).
17    /// The full path is constructed by combining the parent, base, and extension.
18    /// For example, if the module is `"java.base"`, parent is `"java/lang"`,
19    /// base is `"String"`, and extension is `"class"`, the full path will be
20    /// `"java/lang/String.class"`.
21    pub fn get_full_name(&self) -> (String, String) {
22        let mut full_name = String::new();
23
24        full_name.push_str(self.parent.as_ref());
25        if !self.parent.is_empty() {
26            full_name.push('/');
27        }
28
29        full_name.push_str(self.base.as_ref());
30        if !self.extension.is_empty() {
31            full_name.push('.');
32        }
33        full_name.push_str(self.extension.as_ref());
34
35        (self.module.to_string(), full_name)
36    }
37}
38
39/// An iterator over the resource names in a JImage file.
40pub struct ResourceNamesIter<'a> {
41    jimage: &'a JImage,
42    front_index: usize,
43    back_index: usize,
44}
45
46impl<'a> ResourceNamesIter<'a> {
47    pub fn new(jimage: &'a JImage) -> Self {
48        Self {
49            jimage,
50            front_index: 0,
51            back_index: jimage.items_count(),
52        }
53    }
54}
55
56impl<'a> Iterator for ResourceNamesIter<'a> {
57    type Item = Result<ResourceName<'a>>;
58    fn next(&mut self) -> Option<Self::Item> {
59        while self.front_index < self.back_index {
60            let idx = self.front_index;
61            self.front_index += 1;
62            match self.jimage.resource_at_index(idx) {
63                Ok(Some(r)) => return Some(Ok(r)),
64                Ok(None) => continue,
65                Err(e) => return Some(Err(e)),
66            }
67        }
68        None
69    }
70
71    fn size_hint(&self) -> (usize, Option<usize>) {
72        (0, Some(self.back_index.saturating_sub(self.front_index)))
73    }
74}
75
76impl<'a> DoubleEndedIterator for ResourceNamesIter<'a> {
77    fn next_back(&mut self) -> Option<Self::Item> {
78        while self.front_index < self.back_index {
79            self.back_index -= 1;
80            match self.jimage.resource_at_index(self.back_index) {
81                Ok(Some(r)) => return Some(Ok(r)),
82                Ok(None) => continue,
83                Err(e) => return Some(Err(e)),
84            }
85        }
86        None
87    }
88}
89
90impl FusedIterator for ResourceNamesIter<'_> {}