1#[derive(Copy, Clone, Debug)]
4pub struct Args {
6 argc: usize,
7 argv: *const *const u8,
8}
9
10impl Args {
11 pub unsafe fn new(argc: isize, argv: *const *const u8) -> Result<Self, (usize, core::str::Utf8Error)> {
17 assert!(argc > 0);
18 assert!(!argv.is_null());
19
20 let this = Args {
21 argc: argc as usize,
22 argv,
23 };
24
25 let args = this.as_slice();
26 for idx in 0..this.argc {
27 let arg = *args.get_unchecked(idx);
28 if let Err(error) = crate::c_str_to_rust(arg) {
29 return Err((idx, error));
30 }
31 }
32
33 Ok(this)
34 }
35
36 #[inline(always)]
37 pub unsafe fn new_unchecked(argc: isize, argv: *const *const u8) -> Self {
41 Args {
42 argc: argc as usize,
43 argv,
44 }
45 }
46
47 #[inline(always)]
48 pub fn as_slice(&self) -> &[*const u8] {
50 unsafe {
51 core::slice::from_raw_parts(self.argv, self.argc)
52 }
53 }
54
55 #[inline(always)]
56 pub unsafe fn get_str_by_index(&self, index: usize) -> &str {
60 let elem = *self.as_slice().get_unchecked(index);
61 crate::c_str_to_rust_unchecked(elem)
62 }
63}
64
65impl<'a> IntoIterator for &'a Args {
66 type Item = &'a str;
67 type IntoIter = IntoIter<'a>;
68
69 #[inline(always)]
70 fn into_iter(self) -> Self::IntoIter {
71 Self::IntoIter {
72 inner: self,
73 index: 0,
74 }
75 }
76}
77
78pub struct IntoIter<'a> {
82 inner: &'a Args,
83 index: usize,
84}
85
86impl<'a> Iterator for IntoIter<'a> {
87 type Item = &'a str;
88
89 fn next(&mut self) -> Option<Self::Item> {
90 if self.index >= self.inner.argc {
91 return None;
92 }
93
94 let elem = unsafe {
95 self.inner.get_str_by_index(self.index)
96 };
97 self.index += 1;
98 Some(elem)
99 }
100
101 #[inline(always)]
102 fn size_hint(&self) -> (usize, Option<usize>) {
103 let count = self.inner.argc - self.index;
104 (count, Some(count))
105 }
106
107 #[inline(always)]
108 fn count(self) -> usize {
109 self.inner.argc - self.index
110 }
111}
112