1use core::fmt;
4
5use crate::backend::c;
6use crate::ffi;
7
8pub type RawGid = ffi::c_uint;
10pub type RawUid = ffi::c_uint;
12
13#[repr(transparent)]
15#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
16pub struct Uid(RawUid);
17
18#[repr(transparent)]
20#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
21pub struct Gid(RawGid);
22
23impl Uid {
24 pub const ROOT: Self = Self(0);
26
27 #[inline]
31 pub fn from_raw(raw: RawUid) -> Self {
32 debug_assert_ne!(raw, !0);
33 Self(raw)
34 }
35
36 #[inline]
40 pub const fn from_raw_unchecked(raw: RawUid) -> Self {
41 Self(raw)
42 }
43
44 #[inline]
46 pub const fn as_raw(self) -> RawUid {
47 self.0
48 }
49
50 #[inline]
52 pub const fn is_root(self) -> bool {
53 self.0 == Self::ROOT.0
54 }
55}
56
57impl Gid {
58 pub const ROOT: Self = Self(0);
60
61 #[inline]
65 pub fn from_raw(raw: RawGid) -> Self {
66 debug_assert_ne!(raw, !0);
67 Self(raw)
68 }
69
70 #[inline]
74 pub const fn from_raw_unchecked(raw: RawGid) -> Self {
75 Self(raw)
76 }
77
78 #[inline]
80 pub const fn as_raw(self) -> RawGid {
81 self.0
82 }
83
84 #[inline]
86 pub const fn is_root(self) -> bool {
87 self.0 == Self::ROOT.0
88 }
89}
90
91impl fmt::Display for Uid {
92 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93 self.0.fmt(f)
94 }
95}
96impl fmt::Binary for Uid {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 self.0.fmt(f)
99 }
100}
101impl fmt::Octal for Uid {
102 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103 self.0.fmt(f)
104 }
105}
106impl fmt::LowerHex for Uid {
107 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
108 self.0.fmt(f)
109 }
110}
111impl fmt::UpperHex for Uid {
112 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113 self.0.fmt(f)
114 }
115}
116impl fmt::LowerExp for Uid {
117 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118 self.0.fmt(f)
119 }
120}
121impl fmt::UpperExp for Uid {
122 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123 self.0.fmt(f)
124 }
125}
126
127impl fmt::Display for Gid {
128 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129 self.0.fmt(f)
130 }
131}
132impl fmt::Binary for Gid {
133 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
134 self.0.fmt(f)
135 }
136}
137impl fmt::Octal for Gid {
138 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
139 self.0.fmt(f)
140 }
141}
142impl fmt::LowerHex for Gid {
143 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
144 self.0.fmt(f)
145 }
146}
147impl fmt::UpperHex for Gid {
148 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
149 self.0.fmt(f)
150 }
151}
152impl fmt::LowerExp for Gid {
153 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
154 self.0.fmt(f)
155 }
156}
157impl fmt::UpperExp for Gid {
158 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
159 self.0.fmt(f)
160 }
161}
162
163pub(crate) fn translate_fchown_args(
166 owner: Option<Uid>,
167 group: Option<Gid>,
168) -> (c::uid_t, c::gid_t) {
169 let ow = match owner {
170 Some(o) => o.as_raw(),
171 None => !0,
172 };
173
174 let gr = match group {
175 Some(g) => g.as_raw(),
176 None => !0,
177 };
178
179 (ow as c::uid_t, gr as c::gid_t)
180}
181
182#[cfg(test)]
183mod tests {
184 use super::*;
185
186 #[test]
187 fn test_sizes() {
188 assert_eq_size!(RawUid, u32);
189 assert_eq_size!(RawGid, u32);
190 assert_eq_size!(RawUid, libc::uid_t);
191 assert_eq_size!(RawGid, libc::gid_t);
192 }
193}