1#[derive(Copy, Clone)]
4pub struct Args {
23 argc: usize,
24 argv: *const *const u8,
25}
26
27impl Args {
28 pub unsafe fn new(argc: isize, argv: *const *const u8) -> Result<Self, (usize, core::str::Utf8Error)> {
34 debug_assert!(argc > 0);
35 debug_assert!(!argv.is_null());
36
37 let this = Args {
38 argc: argc as usize,
39 argv,
40 };
41
42 let args = this.as_slice();
43 for idx in 0..this.argc {
44 let arg = *args.get_unchecked(idx);
45 if let Err(error) = crate::c_str_to_rust(arg) {
46 return Err((idx, error));
47 }
48 }
49
50 Ok(this)
51 }
52
53 #[inline(always)]
54 pub unsafe fn new_unchecked(argc: isize, argv: *const *const u8) -> Self {
58 Args {
59 argc: argc as usize,
60 argv,
61 }
62 }
63
64 #[inline(always)]
65 pub fn as_slice(&self) -> &[*const u8] {
67 unsafe {
68 core::slice::from_raw_parts(self.argv, self.argc)
69 }
70 }
71
72 pub unsafe fn get_str_by_index(&self, index: usize) -> &str {
76 let elem = *self.as_slice().get_unchecked(index);
77 crate::c_str_to_rust_unchecked(elem)
78 }
79}
80
81impl<'a> IntoIterator for &'a Args {
82 type Item = &'a str;
83 type IntoIter = IntoIter<'a>;
84
85 fn into_iter(self) -> Self::IntoIter {
86 Self::IntoIter {
87 inner: self,
88 index: 0,
89 }
90 }
91}
92
93pub struct IntoIter<'a> {
97 inner: &'a Args,
98 index: usize,
99}
100
101impl<'a> Iterator for IntoIter<'a> {
102 type Item = &'a str;
103
104 fn next(&mut self) -> Option<Self::Item> {
105 if self.index >= self.inner.argc {
106 return None;
107 }
108
109 let elem = unsafe { self.inner.get_str_by_index(self.index) };
110 self.index += 1;
111 Some(elem)
112 }
113
114 fn size_hint(&self) -> (usize, Option<usize>) {
115 let count = self.inner.argc - self.index;
116 (count, Some(count))
117 }
118
119 fn count(self) -> usize {
120 self.inner.argc - self.index
121 }
122}