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