Skip to main content

netlink_bindings/nfsd/
mod.rs

1#![doc = "NFSD configuration over generic netlink.\n"]
2#![allow(clippy::all)]
3#![allow(unused_imports)]
4#![allow(unused_assignments)]
5#![allow(non_snake_case)]
6#![allow(unused_variables)]
7#![allow(irrefutable_let_patterns)]
8#![allow(unreachable_code)]
9#![allow(unreachable_patterns)]
10use crate::builtin::{BuiltinBitfield32, BuiltinNfgenmsg, Nlmsghdr, PushDummy};
11use crate::{
12    consts,
13    traits::{NetlinkRequest, Protocol},
14    utils::*,
15};
16pub const PROTONAME: &str = "nfsd";
17pub const PROTONAME_CSTR: &CStr = c"nfsd";
18#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
19#[derive(Debug, Clone, Copy)]
20pub enum CacheType {
21    SvcExport = 1 << 0,
22    Expkey = 1 << 1,
23}
24impl CacheType {
25    pub fn from_value(value: u64) -> Option<Self> {
26        Some(match value {
27            n if n == 1 << 0 => Self::SvcExport,
28            n if n == 1 << 1 => Self::Expkey,
29            _ => return None,
30        })
31    }
32}
33#[doc = "These flags are ordered to match the [NFSEXP]()\\* flags in\ninclude/linux/nfsd/export.h\n"]
34#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
35#[derive(Debug, Clone, Copy)]
36pub enum ExportFlags {
37    Readonly = 1 << 0,
38    InsecurePort = 1 << 1,
39    Rootsquash = 1 << 2,
40    Allsquash = 1 << 3,
41    Async = 1 << 4,
42    GatheredWrites = 1 << 5,
43    Noreaddirplus = 1 << 6,
44    SecurityLabel = 1 << 7,
45    SignFh = 1 << 8,
46    Nohide = 1 << 9,
47    Nosubtreecheck = 1 << 10,
48    Noauthnlm = 1 << 11,
49    Msnfs = 1 << 12,
50    Fsid = 1 << 13,
51    Crossmount = 1 << 14,
52    Noacl = 1 << 15,
53    V4root = 1 << 16,
54    Pnfs = 1 << 17,
55}
56impl ExportFlags {
57    pub fn from_value(value: u64) -> Option<Self> {
58        Some(match value {
59            n if n == 1 << 0 => Self::Readonly,
60            n if n == 1 << 1 => Self::InsecurePort,
61            n if n == 1 << 2 => Self::Rootsquash,
62            n if n == 1 << 3 => Self::Allsquash,
63            n if n == 1 << 4 => Self::Async,
64            n if n == 1 << 5 => Self::GatheredWrites,
65            n if n == 1 << 6 => Self::Noreaddirplus,
66            n if n == 1 << 7 => Self::SecurityLabel,
67            n if n == 1 << 8 => Self::SignFh,
68            n if n == 1 << 9 => Self::Nohide,
69            n if n == 1 << 10 => Self::Nosubtreecheck,
70            n if n == 1 << 11 => Self::Noauthnlm,
71            n if n == 1 << 12 => Self::Msnfs,
72            n if n == 1 << 13 => Self::Fsid,
73            n if n == 1 << 14 => Self::Crossmount,
74            n if n == 1 << 15 => Self::Noacl,
75            n if n == 1 << 16 => Self::V4root,
76            n if n == 1 << 17 => Self::Pnfs,
77            _ => return None,
78        })
79    }
80}
81#[doc = "These flags are ordered to match the [NFSEXP_XPRTSEC]()\\* flags in\ninclude/linux/nfsd/export.h\n"]
82#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
83#[derive(Debug, Clone, Copy)]
84pub enum XprtsecMode {
85    None = 1 << 0,
86    Tls = 1 << 1,
87    Mtls = 1 << 2,
88}
89impl XprtsecMode {
90    pub fn from_value(value: u64) -> Option<Self> {
91        Some(match value {
92            n if n == 1 << 0 => Self::None,
93            n if n == 1 << 1 => Self::Tls,
94            n if n == 1 << 2 => Self::Mtls,
95            _ => return None,
96        })
97    }
98}
99#[derive(Clone)]
100pub enum CacheNotify {
101    #[doc = "Associated type: [`CacheType`] (enum)"]
102    CacheType(u32),
103}
104impl<'a> IterableCacheNotify<'a> {
105    #[doc = "Associated type: [`CacheType`] (enum)"]
106    pub fn get_cache_type(&self) -> Result<u32, ErrorContext> {
107        let mut iter = self.clone();
108        iter.pos = 0;
109        for attr in iter {
110            if let Ok(CacheNotify::CacheType(val)) = attr {
111                return Ok(val);
112            }
113        }
114        Err(ErrorContext::new_missing(
115            "CacheNotify",
116            "CacheType",
117            self.orig_loc,
118            self.buf.as_ptr() as usize,
119        ))
120    }
121}
122impl CacheNotify {
123    pub fn new<'a>(buf: &'a [u8]) -> IterableCacheNotify<'a> {
124        IterableCacheNotify::with_loc(buf, buf.as_ptr() as usize)
125    }
126    fn attr_from_type(r#type: u16) -> Option<&'static str> {
127        let res = match r#type {
128            1u16 => "CacheType",
129            _ => return None,
130        };
131        Some(res)
132    }
133}
134#[derive(Clone, Copy, Default)]
135pub struct IterableCacheNotify<'a> {
136    buf: &'a [u8],
137    pos: usize,
138    orig_loc: usize,
139}
140impl<'a> IterableCacheNotify<'a> {
141    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
142        Self {
143            buf,
144            pos: 0,
145            orig_loc,
146        }
147    }
148    pub fn get_buf(&self) -> &'a [u8] {
149        self.buf
150    }
151}
152impl<'a> Iterator for IterableCacheNotify<'a> {
153    type Item = Result<CacheNotify, ErrorContext>;
154    fn next(&mut self) -> Option<Self::Item> {
155        let mut pos;
156        let mut r#type;
157        loop {
158            pos = self.pos;
159            r#type = None;
160            if self.buf.len() == self.pos {
161                return None;
162            }
163            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
164                self.pos = self.buf.len();
165                break;
166            };
167            r#type = Some(header.r#type);
168            let res = match header.r#type {
169                1u16 => CacheNotify::CacheType({
170                    let res = parse_u32(next);
171                    let Some(val) = res else { break };
172                    val
173                }),
174                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
175                n => continue,
176            };
177            return Some(Ok(res));
178        }
179        Some(Err(ErrorContext::new(
180            "CacheNotify",
181            r#type.and_then(|t| CacheNotify::attr_from_type(t)),
182            self.orig_loc,
183            self.buf.as_ptr().wrapping_add(pos) as usize,
184        )))
185    }
186}
187impl std::fmt::Debug for IterableCacheNotify<'_> {
188    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
189        let mut fmt = f.debug_struct("CacheNotify");
190        for attr in self.clone() {
191            let attr = match attr {
192                Ok(a) => a,
193                Err(err) => {
194                    fmt.finish()?;
195                    f.write_str("Err(")?;
196                    err.fmt(f)?;
197                    return f.write_str(")");
198                }
199            };
200            match attr {
201                CacheNotify::CacheType(val) => {
202                    fmt.field("CacheType", &FormatFlags(val.into(), CacheType::from_value))
203                }
204            };
205        }
206        fmt.finish()
207    }
208}
209impl IterableCacheNotify<'_> {
210    pub fn lookup_attr(
211        &self,
212        offset: usize,
213        missing_type: Option<u16>,
214    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
215        let mut stack = Vec::new();
216        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
217        if missing_type.is_some() && cur == offset {
218            stack.push(("CacheNotify", offset));
219            return (
220                stack,
221                missing_type.and_then(|t| CacheNotify::attr_from_type(t)),
222            );
223        }
224        if cur > offset || cur + self.buf.len() < offset {
225            return (stack, None);
226        }
227        let mut attrs = self.clone();
228        let mut last_off = cur + attrs.pos;
229        while let Some(attr) = attrs.next() {
230            let Ok(attr) = attr else { break };
231            match attr {
232                CacheNotify::CacheType(val) => {
233                    if last_off == offset {
234                        stack.push(("CacheType", last_off));
235                        break;
236                    }
237                }
238                _ => {}
239            };
240            last_off = cur + attrs.pos;
241        }
242        if !stack.is_empty() {
243            stack.push(("CacheNotify", cur));
244        }
245        (stack, None)
246    }
247}
248#[derive(Clone)]
249pub enum RpcStatus<'a> {
250    Xid(u32),
251    Flags(u32),
252    Prog(u32),
253    Version(u8),
254    Proc(u32),
255    ServiceTime(i64),
256    Pad(&'a [u8]),
257    Saddr4(std::net::Ipv4Addr),
258    Daddr4(std::net::Ipv4Addr),
259    Saddr6(&'a [u8]),
260    Daddr6(&'a [u8]),
261    Sport(u16),
262    Dport(u16),
263    #[doc = "Attribute may repeat multiple times (treat it as array)"]
264    CompoundOps(u32),
265}
266impl<'a> IterableRpcStatus<'a> {
267    pub fn get_xid(&self) -> Result<u32, ErrorContext> {
268        let mut iter = self.clone();
269        iter.pos = 0;
270        for attr in iter {
271            if let Ok(RpcStatus::Xid(val)) = attr {
272                return Ok(val);
273            }
274        }
275        Err(ErrorContext::new_missing(
276            "RpcStatus",
277            "Xid",
278            self.orig_loc,
279            self.buf.as_ptr() as usize,
280        ))
281    }
282    pub fn get_flags(&self) -> Result<u32, ErrorContext> {
283        let mut iter = self.clone();
284        iter.pos = 0;
285        for attr in iter {
286            if let Ok(RpcStatus::Flags(val)) = attr {
287                return Ok(val);
288            }
289        }
290        Err(ErrorContext::new_missing(
291            "RpcStatus",
292            "Flags",
293            self.orig_loc,
294            self.buf.as_ptr() as usize,
295        ))
296    }
297    pub fn get_prog(&self) -> Result<u32, ErrorContext> {
298        let mut iter = self.clone();
299        iter.pos = 0;
300        for attr in iter {
301            if let Ok(RpcStatus::Prog(val)) = attr {
302                return Ok(val);
303            }
304        }
305        Err(ErrorContext::new_missing(
306            "RpcStatus",
307            "Prog",
308            self.orig_loc,
309            self.buf.as_ptr() as usize,
310        ))
311    }
312    pub fn get_version(&self) -> Result<u8, ErrorContext> {
313        let mut iter = self.clone();
314        iter.pos = 0;
315        for attr in iter {
316            if let Ok(RpcStatus::Version(val)) = attr {
317                return Ok(val);
318            }
319        }
320        Err(ErrorContext::new_missing(
321            "RpcStatus",
322            "Version",
323            self.orig_loc,
324            self.buf.as_ptr() as usize,
325        ))
326    }
327    pub fn get_proc(&self) -> Result<u32, ErrorContext> {
328        let mut iter = self.clone();
329        iter.pos = 0;
330        for attr in iter {
331            if let Ok(RpcStatus::Proc(val)) = attr {
332                return Ok(val);
333            }
334        }
335        Err(ErrorContext::new_missing(
336            "RpcStatus",
337            "Proc",
338            self.orig_loc,
339            self.buf.as_ptr() as usize,
340        ))
341    }
342    pub fn get_service_time(&self) -> Result<i64, ErrorContext> {
343        let mut iter = self.clone();
344        iter.pos = 0;
345        for attr in iter {
346            if let Ok(RpcStatus::ServiceTime(val)) = attr {
347                return Ok(val);
348            }
349        }
350        Err(ErrorContext::new_missing(
351            "RpcStatus",
352            "ServiceTime",
353            self.orig_loc,
354            self.buf.as_ptr() as usize,
355        ))
356    }
357    pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
358        let mut iter = self.clone();
359        iter.pos = 0;
360        for attr in iter {
361            if let Ok(RpcStatus::Pad(val)) = attr {
362                return Ok(val);
363            }
364        }
365        Err(ErrorContext::new_missing(
366            "RpcStatus",
367            "Pad",
368            self.orig_loc,
369            self.buf.as_ptr() as usize,
370        ))
371    }
372    pub fn get_saddr4(&self) -> Result<std::net::Ipv4Addr, ErrorContext> {
373        let mut iter = self.clone();
374        iter.pos = 0;
375        for attr in iter {
376            if let Ok(RpcStatus::Saddr4(val)) = attr {
377                return Ok(val);
378            }
379        }
380        Err(ErrorContext::new_missing(
381            "RpcStatus",
382            "Saddr4",
383            self.orig_loc,
384            self.buf.as_ptr() as usize,
385        ))
386    }
387    pub fn get_daddr4(&self) -> Result<std::net::Ipv4Addr, ErrorContext> {
388        let mut iter = self.clone();
389        iter.pos = 0;
390        for attr in iter {
391            if let Ok(RpcStatus::Daddr4(val)) = attr {
392                return Ok(val);
393            }
394        }
395        Err(ErrorContext::new_missing(
396            "RpcStatus",
397            "Daddr4",
398            self.orig_loc,
399            self.buf.as_ptr() as usize,
400        ))
401    }
402    pub fn get_saddr6(&self) -> Result<&'a [u8], ErrorContext> {
403        let mut iter = self.clone();
404        iter.pos = 0;
405        for attr in iter {
406            if let Ok(RpcStatus::Saddr6(val)) = attr {
407                return Ok(val);
408            }
409        }
410        Err(ErrorContext::new_missing(
411            "RpcStatus",
412            "Saddr6",
413            self.orig_loc,
414            self.buf.as_ptr() as usize,
415        ))
416    }
417    pub fn get_daddr6(&self) -> Result<&'a [u8], ErrorContext> {
418        let mut iter = self.clone();
419        iter.pos = 0;
420        for attr in iter {
421            if let Ok(RpcStatus::Daddr6(val)) = attr {
422                return Ok(val);
423            }
424        }
425        Err(ErrorContext::new_missing(
426            "RpcStatus",
427            "Daddr6",
428            self.orig_loc,
429            self.buf.as_ptr() as usize,
430        ))
431    }
432    pub fn get_sport(&self) -> Result<u16, ErrorContext> {
433        let mut iter = self.clone();
434        iter.pos = 0;
435        for attr in iter {
436            if let Ok(RpcStatus::Sport(val)) = attr {
437                return Ok(val);
438            }
439        }
440        Err(ErrorContext::new_missing(
441            "RpcStatus",
442            "Sport",
443            self.orig_loc,
444            self.buf.as_ptr() as usize,
445        ))
446    }
447    pub fn get_dport(&self) -> Result<u16, ErrorContext> {
448        let mut iter = self.clone();
449        iter.pos = 0;
450        for attr in iter {
451            if let Ok(RpcStatus::Dport(val)) = attr {
452                return Ok(val);
453            }
454        }
455        Err(ErrorContext::new_missing(
456            "RpcStatus",
457            "Dport",
458            self.orig_loc,
459            self.buf.as_ptr() as usize,
460        ))
461    }
462    #[doc = "Attribute may repeat multiple times (treat it as array)"]
463    pub fn get_compound_ops(&self) -> MultiAttrIterable<Self, RpcStatus<'a>, u32> {
464        MultiAttrIterable::new(self.clone(), |variant| {
465            if let RpcStatus::CompoundOps(val) = variant {
466                Some(val)
467            } else {
468                None
469            }
470        })
471    }
472}
473impl RpcStatus<'_> {
474    pub fn new<'a>(buf: &'a [u8]) -> IterableRpcStatus<'a> {
475        IterableRpcStatus::with_loc(buf, buf.as_ptr() as usize)
476    }
477    fn attr_from_type(r#type: u16) -> Option<&'static str> {
478        let res = match r#type {
479            1u16 => "Xid",
480            2u16 => "Flags",
481            3u16 => "Prog",
482            4u16 => "Version",
483            5u16 => "Proc",
484            6u16 => "ServiceTime",
485            7u16 => "Pad",
486            8u16 => "Saddr4",
487            9u16 => "Daddr4",
488            10u16 => "Saddr6",
489            11u16 => "Daddr6",
490            12u16 => "Sport",
491            13u16 => "Dport",
492            14u16 => "CompoundOps",
493            _ => return None,
494        };
495        Some(res)
496    }
497}
498#[derive(Clone, Copy, Default)]
499pub struct IterableRpcStatus<'a> {
500    buf: &'a [u8],
501    pos: usize,
502    orig_loc: usize,
503}
504impl<'a> IterableRpcStatus<'a> {
505    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
506        Self {
507            buf,
508            pos: 0,
509            orig_loc,
510        }
511    }
512    pub fn get_buf(&self) -> &'a [u8] {
513        self.buf
514    }
515}
516impl<'a> Iterator for IterableRpcStatus<'a> {
517    type Item = Result<RpcStatus<'a>, ErrorContext>;
518    fn next(&mut self) -> Option<Self::Item> {
519        let mut pos;
520        let mut r#type;
521        loop {
522            pos = self.pos;
523            r#type = None;
524            if self.buf.len() == self.pos {
525                return None;
526            }
527            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
528                self.pos = self.buf.len();
529                break;
530            };
531            r#type = Some(header.r#type);
532            let res = match header.r#type {
533                1u16 => RpcStatus::Xid({
534                    let res = parse_be_u32(next);
535                    let Some(val) = res else { break };
536                    val
537                }),
538                2u16 => RpcStatus::Flags({
539                    let res = parse_u32(next);
540                    let Some(val) = res else { break };
541                    val
542                }),
543                3u16 => RpcStatus::Prog({
544                    let res = parse_u32(next);
545                    let Some(val) = res else { break };
546                    val
547                }),
548                4u16 => RpcStatus::Version({
549                    let res = parse_u8(next);
550                    let Some(val) = res else { break };
551                    val
552                }),
553                5u16 => RpcStatus::Proc({
554                    let res = parse_u32(next);
555                    let Some(val) = res else { break };
556                    val
557                }),
558                6u16 => RpcStatus::ServiceTime({
559                    let res = parse_i64(next);
560                    let Some(val) = res else { break };
561                    val
562                }),
563                7u16 => RpcStatus::Pad({
564                    let res = Some(next);
565                    let Some(val) = res else { break };
566                    val
567                }),
568                8u16 => RpcStatus::Saddr4({
569                    let res = parse_be_u32(next).map(Ipv4Addr::from_bits);
570                    let Some(val) = res else { break };
571                    val
572                }),
573                9u16 => RpcStatus::Daddr4({
574                    let res = parse_be_u32(next).map(Ipv4Addr::from_bits);
575                    let Some(val) = res else { break };
576                    val
577                }),
578                10u16 => RpcStatus::Saddr6({
579                    let res = Some(next);
580                    let Some(val) = res else { break };
581                    val
582                }),
583                11u16 => RpcStatus::Daddr6({
584                    let res = Some(next);
585                    let Some(val) = res else { break };
586                    val
587                }),
588                12u16 => RpcStatus::Sport({
589                    let res = parse_be_u16(next);
590                    let Some(val) = res else { break };
591                    val
592                }),
593                13u16 => RpcStatus::Dport({
594                    let res = parse_be_u16(next);
595                    let Some(val) = res else { break };
596                    val
597                }),
598                14u16 => RpcStatus::CompoundOps({
599                    let res = parse_u32(next);
600                    let Some(val) = res else { break };
601                    val
602                }),
603                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
604                n => continue,
605            };
606            return Some(Ok(res));
607        }
608        Some(Err(ErrorContext::new(
609            "RpcStatus",
610            r#type.and_then(|t| RpcStatus::attr_from_type(t)),
611            self.orig_loc,
612            self.buf.as_ptr().wrapping_add(pos) as usize,
613        )))
614    }
615}
616impl<'a> std::fmt::Debug for IterableRpcStatus<'_> {
617    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
618        let mut fmt = f.debug_struct("RpcStatus");
619        for attr in self.clone() {
620            let attr = match attr {
621                Ok(a) => a,
622                Err(err) => {
623                    fmt.finish()?;
624                    f.write_str("Err(")?;
625                    err.fmt(f)?;
626                    return f.write_str(")");
627                }
628            };
629            match attr {
630                RpcStatus::Xid(val) => fmt.field("Xid", &val),
631                RpcStatus::Flags(val) => fmt.field("Flags", &val),
632                RpcStatus::Prog(val) => fmt.field("Prog", &val),
633                RpcStatus::Version(val) => fmt.field("Version", &val),
634                RpcStatus::Proc(val) => fmt.field("Proc", &val),
635                RpcStatus::ServiceTime(val) => fmt.field("ServiceTime", &val),
636                RpcStatus::Pad(val) => fmt.field("Pad", &val),
637                RpcStatus::Saddr4(val) => fmt.field("Saddr4", &val),
638                RpcStatus::Daddr4(val) => fmt.field("Daddr4", &val),
639                RpcStatus::Saddr6(val) => fmt.field("Saddr6", &val),
640                RpcStatus::Daddr6(val) => fmt.field("Daddr6", &val),
641                RpcStatus::Sport(val) => fmt.field("Sport", &val),
642                RpcStatus::Dport(val) => fmt.field("Dport", &val),
643                RpcStatus::CompoundOps(val) => fmt.field("CompoundOps", &val),
644            };
645        }
646        fmt.finish()
647    }
648}
649impl IterableRpcStatus<'_> {
650    pub fn lookup_attr(
651        &self,
652        offset: usize,
653        missing_type: Option<u16>,
654    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
655        let mut stack = Vec::new();
656        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
657        if missing_type.is_some() && cur == offset {
658            stack.push(("RpcStatus", offset));
659            return (
660                stack,
661                missing_type.and_then(|t| RpcStatus::attr_from_type(t)),
662            );
663        }
664        if cur > offset || cur + self.buf.len() < offset {
665            return (stack, None);
666        }
667        let mut attrs = self.clone();
668        let mut last_off = cur + attrs.pos;
669        while let Some(attr) = attrs.next() {
670            let Ok(attr) = attr else { break };
671            match attr {
672                RpcStatus::Xid(val) => {
673                    if last_off == offset {
674                        stack.push(("Xid", last_off));
675                        break;
676                    }
677                }
678                RpcStatus::Flags(val) => {
679                    if last_off == offset {
680                        stack.push(("Flags", last_off));
681                        break;
682                    }
683                }
684                RpcStatus::Prog(val) => {
685                    if last_off == offset {
686                        stack.push(("Prog", last_off));
687                        break;
688                    }
689                }
690                RpcStatus::Version(val) => {
691                    if last_off == offset {
692                        stack.push(("Version", last_off));
693                        break;
694                    }
695                }
696                RpcStatus::Proc(val) => {
697                    if last_off == offset {
698                        stack.push(("Proc", last_off));
699                        break;
700                    }
701                }
702                RpcStatus::ServiceTime(val) => {
703                    if last_off == offset {
704                        stack.push(("ServiceTime", last_off));
705                        break;
706                    }
707                }
708                RpcStatus::Pad(val) => {
709                    if last_off == offset {
710                        stack.push(("Pad", last_off));
711                        break;
712                    }
713                }
714                RpcStatus::Saddr4(val) => {
715                    if last_off == offset {
716                        stack.push(("Saddr4", last_off));
717                        break;
718                    }
719                }
720                RpcStatus::Daddr4(val) => {
721                    if last_off == offset {
722                        stack.push(("Daddr4", last_off));
723                        break;
724                    }
725                }
726                RpcStatus::Saddr6(val) => {
727                    if last_off == offset {
728                        stack.push(("Saddr6", last_off));
729                        break;
730                    }
731                }
732                RpcStatus::Daddr6(val) => {
733                    if last_off == offset {
734                        stack.push(("Daddr6", last_off));
735                        break;
736                    }
737                }
738                RpcStatus::Sport(val) => {
739                    if last_off == offset {
740                        stack.push(("Sport", last_off));
741                        break;
742                    }
743                }
744                RpcStatus::Dport(val) => {
745                    if last_off == offset {
746                        stack.push(("Dport", last_off));
747                        break;
748                    }
749                }
750                RpcStatus::CompoundOps(val) => {
751                    if last_off == offset {
752                        stack.push(("CompoundOps", last_off));
753                        break;
754                    }
755                }
756                _ => {}
757            };
758            last_off = cur + attrs.pos;
759        }
760        if !stack.is_empty() {
761            stack.push(("RpcStatus", cur));
762        }
763        (stack, None)
764    }
765}
766#[derive(Clone)]
767pub enum Server<'a> {
768    #[doc = "Attribute may repeat multiple times (treat it as array)"]
769    Threads(u32),
770    Gracetime(u32),
771    Leasetime(u32),
772    Scope(&'a CStr),
773    MinThreads(u32),
774    FhKey(&'a [u8]),
775}
776impl<'a> IterableServer<'a> {
777    #[doc = "Attribute may repeat multiple times (treat it as array)"]
778    pub fn get_threads(&self) -> MultiAttrIterable<Self, Server<'a>, u32> {
779        MultiAttrIterable::new(self.clone(), |variant| {
780            if let Server::Threads(val) = variant {
781                Some(val)
782            } else {
783                None
784            }
785        })
786    }
787    pub fn get_gracetime(&self) -> Result<u32, ErrorContext> {
788        let mut iter = self.clone();
789        iter.pos = 0;
790        for attr in iter {
791            if let Ok(Server::Gracetime(val)) = attr {
792                return Ok(val);
793            }
794        }
795        Err(ErrorContext::new_missing(
796            "Server",
797            "Gracetime",
798            self.orig_loc,
799            self.buf.as_ptr() as usize,
800        ))
801    }
802    pub fn get_leasetime(&self) -> Result<u32, ErrorContext> {
803        let mut iter = self.clone();
804        iter.pos = 0;
805        for attr in iter {
806            if let Ok(Server::Leasetime(val)) = attr {
807                return Ok(val);
808            }
809        }
810        Err(ErrorContext::new_missing(
811            "Server",
812            "Leasetime",
813            self.orig_loc,
814            self.buf.as_ptr() as usize,
815        ))
816    }
817    pub fn get_scope(&self) -> Result<&'a CStr, ErrorContext> {
818        let mut iter = self.clone();
819        iter.pos = 0;
820        for attr in iter {
821            if let Ok(Server::Scope(val)) = attr {
822                return Ok(val);
823            }
824        }
825        Err(ErrorContext::new_missing(
826            "Server",
827            "Scope",
828            self.orig_loc,
829            self.buf.as_ptr() as usize,
830        ))
831    }
832    pub fn get_min_threads(&self) -> Result<u32, ErrorContext> {
833        let mut iter = self.clone();
834        iter.pos = 0;
835        for attr in iter {
836            if let Ok(Server::MinThreads(val)) = attr {
837                return Ok(val);
838            }
839        }
840        Err(ErrorContext::new_missing(
841            "Server",
842            "MinThreads",
843            self.orig_loc,
844            self.buf.as_ptr() as usize,
845        ))
846    }
847    pub fn get_fh_key(&self) -> Result<&'a [u8], ErrorContext> {
848        let mut iter = self.clone();
849        iter.pos = 0;
850        for attr in iter {
851            if let Ok(Server::FhKey(val)) = attr {
852                return Ok(val);
853            }
854        }
855        Err(ErrorContext::new_missing(
856            "Server",
857            "FhKey",
858            self.orig_loc,
859            self.buf.as_ptr() as usize,
860        ))
861    }
862}
863impl Server<'_> {
864    pub fn new<'a>(buf: &'a [u8]) -> IterableServer<'a> {
865        IterableServer::with_loc(buf, buf.as_ptr() as usize)
866    }
867    fn attr_from_type(r#type: u16) -> Option<&'static str> {
868        let res = match r#type {
869            1u16 => "Threads",
870            2u16 => "Gracetime",
871            3u16 => "Leasetime",
872            4u16 => "Scope",
873            5u16 => "MinThreads",
874            6u16 => "FhKey",
875            _ => return None,
876        };
877        Some(res)
878    }
879}
880#[derive(Clone, Copy, Default)]
881pub struct IterableServer<'a> {
882    buf: &'a [u8],
883    pos: usize,
884    orig_loc: usize,
885}
886impl<'a> IterableServer<'a> {
887    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
888        Self {
889            buf,
890            pos: 0,
891            orig_loc,
892        }
893    }
894    pub fn get_buf(&self) -> &'a [u8] {
895        self.buf
896    }
897}
898impl<'a> Iterator for IterableServer<'a> {
899    type Item = Result<Server<'a>, ErrorContext>;
900    fn next(&mut self) -> Option<Self::Item> {
901        let mut pos;
902        let mut r#type;
903        loop {
904            pos = self.pos;
905            r#type = None;
906            if self.buf.len() == self.pos {
907                return None;
908            }
909            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
910                self.pos = self.buf.len();
911                break;
912            };
913            r#type = Some(header.r#type);
914            let res = match header.r#type {
915                1u16 => Server::Threads({
916                    let res = parse_u32(next);
917                    let Some(val) = res else { break };
918                    val
919                }),
920                2u16 => Server::Gracetime({
921                    let res = parse_u32(next);
922                    let Some(val) = res else { break };
923                    val
924                }),
925                3u16 => Server::Leasetime({
926                    let res = parse_u32(next);
927                    let Some(val) = res else { break };
928                    val
929                }),
930                4u16 => Server::Scope({
931                    let res = CStr::from_bytes_with_nul(next).ok();
932                    let Some(val) = res else { break };
933                    val
934                }),
935                5u16 => Server::MinThreads({
936                    let res = parse_u32(next);
937                    let Some(val) = res else { break };
938                    val
939                }),
940                6u16 => Server::FhKey({
941                    let res = Some(next);
942                    let Some(val) = res else { break };
943                    val
944                }),
945                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
946                n => continue,
947            };
948            return Some(Ok(res));
949        }
950        Some(Err(ErrorContext::new(
951            "Server",
952            r#type.and_then(|t| Server::attr_from_type(t)),
953            self.orig_loc,
954            self.buf.as_ptr().wrapping_add(pos) as usize,
955        )))
956    }
957}
958impl<'a> std::fmt::Debug for IterableServer<'_> {
959    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
960        let mut fmt = f.debug_struct("Server");
961        for attr in self.clone() {
962            let attr = match attr {
963                Ok(a) => a,
964                Err(err) => {
965                    fmt.finish()?;
966                    f.write_str("Err(")?;
967                    err.fmt(f)?;
968                    return f.write_str(")");
969                }
970            };
971            match attr {
972                Server::Threads(val) => fmt.field("Threads", &val),
973                Server::Gracetime(val) => fmt.field("Gracetime", &val),
974                Server::Leasetime(val) => fmt.field("Leasetime", &val),
975                Server::Scope(val) => fmt.field("Scope", &val),
976                Server::MinThreads(val) => fmt.field("MinThreads", &val),
977                Server::FhKey(val) => fmt.field("FhKey", &val),
978            };
979        }
980        fmt.finish()
981    }
982}
983impl IterableServer<'_> {
984    pub fn lookup_attr(
985        &self,
986        offset: usize,
987        missing_type: Option<u16>,
988    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
989        let mut stack = Vec::new();
990        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
991        if missing_type.is_some() && cur == offset {
992            stack.push(("Server", offset));
993            return (stack, missing_type.and_then(|t| Server::attr_from_type(t)));
994        }
995        if cur > offset || cur + self.buf.len() < offset {
996            return (stack, None);
997        }
998        let mut attrs = self.clone();
999        let mut last_off = cur + attrs.pos;
1000        while let Some(attr) = attrs.next() {
1001            let Ok(attr) = attr else { break };
1002            match attr {
1003                Server::Threads(val) => {
1004                    if last_off == offset {
1005                        stack.push(("Threads", last_off));
1006                        break;
1007                    }
1008                }
1009                Server::Gracetime(val) => {
1010                    if last_off == offset {
1011                        stack.push(("Gracetime", last_off));
1012                        break;
1013                    }
1014                }
1015                Server::Leasetime(val) => {
1016                    if last_off == offset {
1017                        stack.push(("Leasetime", last_off));
1018                        break;
1019                    }
1020                }
1021                Server::Scope(val) => {
1022                    if last_off == offset {
1023                        stack.push(("Scope", last_off));
1024                        break;
1025                    }
1026                }
1027                Server::MinThreads(val) => {
1028                    if last_off == offset {
1029                        stack.push(("MinThreads", last_off));
1030                        break;
1031                    }
1032                }
1033                Server::FhKey(val) => {
1034                    if last_off == offset {
1035                        stack.push(("FhKey", last_off));
1036                        break;
1037                    }
1038                }
1039                _ => {}
1040            };
1041            last_off = cur + attrs.pos;
1042        }
1043        if !stack.is_empty() {
1044            stack.push(("Server", cur));
1045        }
1046        (stack, None)
1047    }
1048}
1049#[derive(Clone)]
1050pub enum Version {
1051    Major(u32),
1052    Minor(u32),
1053    Enabled(()),
1054}
1055impl<'a> IterableVersion<'a> {
1056    pub fn get_major(&self) -> Result<u32, ErrorContext> {
1057        let mut iter = self.clone();
1058        iter.pos = 0;
1059        for attr in iter {
1060            if let Ok(Version::Major(val)) = attr {
1061                return Ok(val);
1062            }
1063        }
1064        Err(ErrorContext::new_missing(
1065            "Version",
1066            "Major",
1067            self.orig_loc,
1068            self.buf.as_ptr() as usize,
1069        ))
1070    }
1071    pub fn get_minor(&self) -> Result<u32, ErrorContext> {
1072        let mut iter = self.clone();
1073        iter.pos = 0;
1074        for attr in iter {
1075            if let Ok(Version::Minor(val)) = attr {
1076                return Ok(val);
1077            }
1078        }
1079        Err(ErrorContext::new_missing(
1080            "Version",
1081            "Minor",
1082            self.orig_loc,
1083            self.buf.as_ptr() as usize,
1084        ))
1085    }
1086    pub fn get_enabled(&self) -> Result<(), ErrorContext> {
1087        let mut iter = self.clone();
1088        iter.pos = 0;
1089        for attr in iter {
1090            if let Ok(Version::Enabled(val)) = attr {
1091                return Ok(val);
1092            }
1093        }
1094        Err(ErrorContext::new_missing(
1095            "Version",
1096            "Enabled",
1097            self.orig_loc,
1098            self.buf.as_ptr() as usize,
1099        ))
1100    }
1101}
1102impl Version {
1103    pub fn new<'a>(buf: &'a [u8]) -> IterableVersion<'a> {
1104        IterableVersion::with_loc(buf, buf.as_ptr() as usize)
1105    }
1106    fn attr_from_type(r#type: u16) -> Option<&'static str> {
1107        let res = match r#type {
1108            1u16 => "Major",
1109            2u16 => "Minor",
1110            3u16 => "Enabled",
1111            _ => return None,
1112        };
1113        Some(res)
1114    }
1115}
1116#[derive(Clone, Copy, Default)]
1117pub struct IterableVersion<'a> {
1118    buf: &'a [u8],
1119    pos: usize,
1120    orig_loc: usize,
1121}
1122impl<'a> IterableVersion<'a> {
1123    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1124        Self {
1125            buf,
1126            pos: 0,
1127            orig_loc,
1128        }
1129    }
1130    pub fn get_buf(&self) -> &'a [u8] {
1131        self.buf
1132    }
1133}
1134impl<'a> Iterator for IterableVersion<'a> {
1135    type Item = Result<Version, ErrorContext>;
1136    fn next(&mut self) -> Option<Self::Item> {
1137        let mut pos;
1138        let mut r#type;
1139        loop {
1140            pos = self.pos;
1141            r#type = None;
1142            if self.buf.len() == self.pos {
1143                return None;
1144            }
1145            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1146                self.pos = self.buf.len();
1147                break;
1148            };
1149            r#type = Some(header.r#type);
1150            let res = match header.r#type {
1151                1u16 => Version::Major({
1152                    let res = parse_u32(next);
1153                    let Some(val) = res else { break };
1154                    val
1155                }),
1156                2u16 => Version::Minor({
1157                    let res = parse_u32(next);
1158                    let Some(val) = res else { break };
1159                    val
1160                }),
1161                3u16 => Version::Enabled(()),
1162                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1163                n => continue,
1164            };
1165            return Some(Ok(res));
1166        }
1167        Some(Err(ErrorContext::new(
1168            "Version",
1169            r#type.and_then(|t| Version::attr_from_type(t)),
1170            self.orig_loc,
1171            self.buf.as_ptr().wrapping_add(pos) as usize,
1172        )))
1173    }
1174}
1175impl std::fmt::Debug for IterableVersion<'_> {
1176    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1177        let mut fmt = f.debug_struct("Version");
1178        for attr in self.clone() {
1179            let attr = match attr {
1180                Ok(a) => a,
1181                Err(err) => {
1182                    fmt.finish()?;
1183                    f.write_str("Err(")?;
1184                    err.fmt(f)?;
1185                    return f.write_str(")");
1186                }
1187            };
1188            match attr {
1189                Version::Major(val) => fmt.field("Major", &val),
1190                Version::Minor(val) => fmt.field("Minor", &val),
1191                Version::Enabled(val) => fmt.field("Enabled", &val),
1192            };
1193        }
1194        fmt.finish()
1195    }
1196}
1197impl IterableVersion<'_> {
1198    pub fn lookup_attr(
1199        &self,
1200        offset: usize,
1201        missing_type: Option<u16>,
1202    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1203        let mut stack = Vec::new();
1204        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1205        if missing_type.is_some() && cur == offset {
1206            stack.push(("Version", offset));
1207            return (stack, missing_type.and_then(|t| Version::attr_from_type(t)));
1208        }
1209        if cur > offset || cur + self.buf.len() < offset {
1210            return (stack, None);
1211        }
1212        let mut attrs = self.clone();
1213        let mut last_off = cur + attrs.pos;
1214        while let Some(attr) = attrs.next() {
1215            let Ok(attr) = attr else { break };
1216            match attr {
1217                Version::Major(val) => {
1218                    if last_off == offset {
1219                        stack.push(("Major", last_off));
1220                        break;
1221                    }
1222                }
1223                Version::Minor(val) => {
1224                    if last_off == offset {
1225                        stack.push(("Minor", last_off));
1226                        break;
1227                    }
1228                }
1229                Version::Enabled(val) => {
1230                    if last_off == offset {
1231                        stack.push(("Enabled", last_off));
1232                        break;
1233                    }
1234                }
1235                _ => {}
1236            };
1237            last_off = cur + attrs.pos;
1238        }
1239        if !stack.is_empty() {
1240            stack.push(("Version", cur));
1241        }
1242        (stack, None)
1243    }
1244}
1245#[derive(Clone)]
1246pub enum ServerProto<'a> {
1247    #[doc = "Attribute may repeat multiple times (treat it as array)"]
1248    Version(IterableVersion<'a>),
1249}
1250impl<'a> IterableServerProto<'a> {
1251    #[doc = "Attribute may repeat multiple times (treat it as array)"]
1252    pub fn get_version(&self) -> MultiAttrIterable<Self, ServerProto<'a>, IterableVersion<'a>> {
1253        MultiAttrIterable::new(self.clone(), |variant| {
1254            if let ServerProto::Version(val) = variant {
1255                Some(val)
1256            } else {
1257                None
1258            }
1259        })
1260    }
1261}
1262impl ServerProto<'_> {
1263    pub fn new<'a>(buf: &'a [u8]) -> IterableServerProto<'a> {
1264        IterableServerProto::with_loc(buf, buf.as_ptr() as usize)
1265    }
1266    fn attr_from_type(r#type: u16) -> Option<&'static str> {
1267        let res = match r#type {
1268            1u16 => "Version",
1269            _ => return None,
1270        };
1271        Some(res)
1272    }
1273}
1274#[derive(Clone, Copy, Default)]
1275pub struct IterableServerProto<'a> {
1276    buf: &'a [u8],
1277    pos: usize,
1278    orig_loc: usize,
1279}
1280impl<'a> IterableServerProto<'a> {
1281    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1282        Self {
1283            buf,
1284            pos: 0,
1285            orig_loc,
1286        }
1287    }
1288    pub fn get_buf(&self) -> &'a [u8] {
1289        self.buf
1290    }
1291}
1292impl<'a> Iterator for IterableServerProto<'a> {
1293    type Item = Result<ServerProto<'a>, ErrorContext>;
1294    fn next(&mut self) -> Option<Self::Item> {
1295        let mut pos;
1296        let mut r#type;
1297        loop {
1298            pos = self.pos;
1299            r#type = None;
1300            if self.buf.len() == self.pos {
1301                return None;
1302            }
1303            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1304                self.pos = self.buf.len();
1305                break;
1306            };
1307            r#type = Some(header.r#type);
1308            let res = match header.r#type {
1309                1u16 => ServerProto::Version({
1310                    let res = Some(IterableVersion::with_loc(next, self.orig_loc));
1311                    let Some(val) = res else { break };
1312                    val
1313                }),
1314                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1315                n => continue,
1316            };
1317            return Some(Ok(res));
1318        }
1319        Some(Err(ErrorContext::new(
1320            "ServerProto",
1321            r#type.and_then(|t| ServerProto::attr_from_type(t)),
1322            self.orig_loc,
1323            self.buf.as_ptr().wrapping_add(pos) as usize,
1324        )))
1325    }
1326}
1327impl<'a> std::fmt::Debug for IterableServerProto<'_> {
1328    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1329        let mut fmt = f.debug_struct("ServerProto");
1330        for attr in self.clone() {
1331            let attr = match attr {
1332                Ok(a) => a,
1333                Err(err) => {
1334                    fmt.finish()?;
1335                    f.write_str("Err(")?;
1336                    err.fmt(f)?;
1337                    return f.write_str(")");
1338                }
1339            };
1340            match attr {
1341                ServerProto::Version(val) => fmt.field("Version", &val),
1342            };
1343        }
1344        fmt.finish()
1345    }
1346}
1347impl IterableServerProto<'_> {
1348    pub fn lookup_attr(
1349        &self,
1350        offset: usize,
1351        missing_type: Option<u16>,
1352    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1353        let mut stack = Vec::new();
1354        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1355        if missing_type.is_some() && cur == offset {
1356            stack.push(("ServerProto", offset));
1357            return (
1358                stack,
1359                missing_type.and_then(|t| ServerProto::attr_from_type(t)),
1360            );
1361        }
1362        if cur > offset || cur + self.buf.len() < offset {
1363            return (stack, None);
1364        }
1365        let mut attrs = self.clone();
1366        let mut last_off = cur + attrs.pos;
1367        let mut missing = None;
1368        while let Some(attr) = attrs.next() {
1369            let Ok(attr) = attr else { break };
1370            match attr {
1371                ServerProto::Version(val) => {
1372                    (stack, missing) = val.lookup_attr(offset, missing_type);
1373                    if !stack.is_empty() {
1374                        break;
1375                    }
1376                }
1377                _ => {}
1378            };
1379            last_off = cur + attrs.pos;
1380        }
1381        if !stack.is_empty() {
1382            stack.push(("ServerProto", cur));
1383        }
1384        (stack, missing)
1385    }
1386}
1387#[derive(Clone)]
1388pub enum Sock<'a> {
1389    Addr(&'a [u8]),
1390    TransportName(&'a CStr),
1391}
1392impl<'a> IterableSock<'a> {
1393    pub fn get_addr(&self) -> Result<&'a [u8], ErrorContext> {
1394        let mut iter = self.clone();
1395        iter.pos = 0;
1396        for attr in iter {
1397            if let Ok(Sock::Addr(val)) = attr {
1398                return Ok(val);
1399            }
1400        }
1401        Err(ErrorContext::new_missing(
1402            "Sock",
1403            "Addr",
1404            self.orig_loc,
1405            self.buf.as_ptr() as usize,
1406        ))
1407    }
1408    pub fn get_transport_name(&self) -> Result<&'a CStr, ErrorContext> {
1409        let mut iter = self.clone();
1410        iter.pos = 0;
1411        for attr in iter {
1412            if let Ok(Sock::TransportName(val)) = attr {
1413                return Ok(val);
1414            }
1415        }
1416        Err(ErrorContext::new_missing(
1417            "Sock",
1418            "TransportName",
1419            self.orig_loc,
1420            self.buf.as_ptr() as usize,
1421        ))
1422    }
1423}
1424impl Sock<'_> {
1425    pub fn new<'a>(buf: &'a [u8]) -> IterableSock<'a> {
1426        IterableSock::with_loc(buf, buf.as_ptr() as usize)
1427    }
1428    fn attr_from_type(r#type: u16) -> Option<&'static str> {
1429        let res = match r#type {
1430            1u16 => "Addr",
1431            2u16 => "TransportName",
1432            _ => return None,
1433        };
1434        Some(res)
1435    }
1436}
1437#[derive(Clone, Copy, Default)]
1438pub struct IterableSock<'a> {
1439    buf: &'a [u8],
1440    pos: usize,
1441    orig_loc: usize,
1442}
1443impl<'a> IterableSock<'a> {
1444    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1445        Self {
1446            buf,
1447            pos: 0,
1448            orig_loc,
1449        }
1450    }
1451    pub fn get_buf(&self) -> &'a [u8] {
1452        self.buf
1453    }
1454}
1455impl<'a> Iterator for IterableSock<'a> {
1456    type Item = Result<Sock<'a>, ErrorContext>;
1457    fn next(&mut self) -> Option<Self::Item> {
1458        let mut pos;
1459        let mut r#type;
1460        loop {
1461            pos = self.pos;
1462            r#type = None;
1463            if self.buf.len() == self.pos {
1464                return None;
1465            }
1466            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1467                self.pos = self.buf.len();
1468                break;
1469            };
1470            r#type = Some(header.r#type);
1471            let res = match header.r#type {
1472                1u16 => Sock::Addr({
1473                    let res = Some(next);
1474                    let Some(val) = res else { break };
1475                    val
1476                }),
1477                2u16 => Sock::TransportName({
1478                    let res = CStr::from_bytes_with_nul(next).ok();
1479                    let Some(val) = res else { break };
1480                    val
1481                }),
1482                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1483                n => continue,
1484            };
1485            return Some(Ok(res));
1486        }
1487        Some(Err(ErrorContext::new(
1488            "Sock",
1489            r#type.and_then(|t| Sock::attr_from_type(t)),
1490            self.orig_loc,
1491            self.buf.as_ptr().wrapping_add(pos) as usize,
1492        )))
1493    }
1494}
1495impl<'a> std::fmt::Debug for IterableSock<'_> {
1496    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1497        let mut fmt = f.debug_struct("Sock");
1498        for attr in self.clone() {
1499            let attr = match attr {
1500                Ok(a) => a,
1501                Err(err) => {
1502                    fmt.finish()?;
1503                    f.write_str("Err(")?;
1504                    err.fmt(f)?;
1505                    return f.write_str(")");
1506                }
1507            };
1508            match attr {
1509                Sock::Addr(val) => fmt.field("Addr", &val),
1510                Sock::TransportName(val) => fmt.field("TransportName", &val),
1511            };
1512        }
1513        fmt.finish()
1514    }
1515}
1516impl IterableSock<'_> {
1517    pub fn lookup_attr(
1518        &self,
1519        offset: usize,
1520        missing_type: Option<u16>,
1521    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1522        let mut stack = Vec::new();
1523        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1524        if missing_type.is_some() && cur == offset {
1525            stack.push(("Sock", offset));
1526            return (stack, missing_type.and_then(|t| Sock::attr_from_type(t)));
1527        }
1528        if cur > offset || cur + self.buf.len() < offset {
1529            return (stack, None);
1530        }
1531        let mut attrs = self.clone();
1532        let mut last_off = cur + attrs.pos;
1533        while let Some(attr) = attrs.next() {
1534            let Ok(attr) = attr else { break };
1535            match attr {
1536                Sock::Addr(val) => {
1537                    if last_off == offset {
1538                        stack.push(("Addr", last_off));
1539                        break;
1540                    }
1541                }
1542                Sock::TransportName(val) => {
1543                    if last_off == offset {
1544                        stack.push(("TransportName", last_off));
1545                        break;
1546                    }
1547                }
1548                _ => {}
1549            };
1550            last_off = cur + attrs.pos;
1551        }
1552        if !stack.is_empty() {
1553            stack.push(("Sock", cur));
1554        }
1555        (stack, None)
1556    }
1557}
1558#[derive(Clone)]
1559pub enum ServerSock<'a> {
1560    #[doc = "Attribute may repeat multiple times (treat it as array)"]
1561    Addr(IterableSock<'a>),
1562}
1563impl<'a> IterableServerSock<'a> {
1564    #[doc = "Attribute may repeat multiple times (treat it as array)"]
1565    pub fn get_addr(&self) -> MultiAttrIterable<Self, ServerSock<'a>, IterableSock<'a>> {
1566        MultiAttrIterable::new(self.clone(), |variant| {
1567            if let ServerSock::Addr(val) = variant {
1568                Some(val)
1569            } else {
1570                None
1571            }
1572        })
1573    }
1574}
1575impl ServerSock<'_> {
1576    pub fn new<'a>(buf: &'a [u8]) -> IterableServerSock<'a> {
1577        IterableServerSock::with_loc(buf, buf.as_ptr() as usize)
1578    }
1579    fn attr_from_type(r#type: u16) -> Option<&'static str> {
1580        let res = match r#type {
1581            1u16 => "Addr",
1582            _ => return None,
1583        };
1584        Some(res)
1585    }
1586}
1587#[derive(Clone, Copy, Default)]
1588pub struct IterableServerSock<'a> {
1589    buf: &'a [u8],
1590    pos: usize,
1591    orig_loc: usize,
1592}
1593impl<'a> IterableServerSock<'a> {
1594    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1595        Self {
1596            buf,
1597            pos: 0,
1598            orig_loc,
1599        }
1600    }
1601    pub fn get_buf(&self) -> &'a [u8] {
1602        self.buf
1603    }
1604}
1605impl<'a> Iterator for IterableServerSock<'a> {
1606    type Item = Result<ServerSock<'a>, ErrorContext>;
1607    fn next(&mut self) -> Option<Self::Item> {
1608        let mut pos;
1609        let mut r#type;
1610        loop {
1611            pos = self.pos;
1612            r#type = None;
1613            if self.buf.len() == self.pos {
1614                return None;
1615            }
1616            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1617                self.pos = self.buf.len();
1618                break;
1619            };
1620            r#type = Some(header.r#type);
1621            let res = match header.r#type {
1622                1u16 => ServerSock::Addr({
1623                    let res = Some(IterableSock::with_loc(next, self.orig_loc));
1624                    let Some(val) = res else { break };
1625                    val
1626                }),
1627                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1628                n => continue,
1629            };
1630            return Some(Ok(res));
1631        }
1632        Some(Err(ErrorContext::new(
1633            "ServerSock",
1634            r#type.and_then(|t| ServerSock::attr_from_type(t)),
1635            self.orig_loc,
1636            self.buf.as_ptr().wrapping_add(pos) as usize,
1637        )))
1638    }
1639}
1640impl<'a> std::fmt::Debug for IterableServerSock<'_> {
1641    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1642        let mut fmt = f.debug_struct("ServerSock");
1643        for attr in self.clone() {
1644            let attr = match attr {
1645                Ok(a) => a,
1646                Err(err) => {
1647                    fmt.finish()?;
1648                    f.write_str("Err(")?;
1649                    err.fmt(f)?;
1650                    return f.write_str(")");
1651                }
1652            };
1653            match attr {
1654                ServerSock::Addr(val) => fmt.field("Addr", &val),
1655            };
1656        }
1657        fmt.finish()
1658    }
1659}
1660impl IterableServerSock<'_> {
1661    pub fn lookup_attr(
1662        &self,
1663        offset: usize,
1664        missing_type: Option<u16>,
1665    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1666        let mut stack = Vec::new();
1667        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1668        if missing_type.is_some() && cur == offset {
1669            stack.push(("ServerSock", offset));
1670            return (
1671                stack,
1672                missing_type.and_then(|t| ServerSock::attr_from_type(t)),
1673            );
1674        }
1675        if cur > offset || cur + self.buf.len() < offset {
1676            return (stack, None);
1677        }
1678        let mut attrs = self.clone();
1679        let mut last_off = cur + attrs.pos;
1680        let mut missing = None;
1681        while let Some(attr) = attrs.next() {
1682            let Ok(attr) = attr else { break };
1683            match attr {
1684                ServerSock::Addr(val) => {
1685                    (stack, missing) = val.lookup_attr(offset, missing_type);
1686                    if !stack.is_empty() {
1687                        break;
1688                    }
1689                }
1690                _ => {}
1691            };
1692            last_off = cur + attrs.pos;
1693        }
1694        if !stack.is_empty() {
1695            stack.push(("ServerSock", cur));
1696        }
1697        (stack, missing)
1698    }
1699}
1700#[derive(Clone)]
1701pub enum PoolMode<'a> {
1702    Mode(&'a CStr),
1703    Npools(u32),
1704}
1705impl<'a> IterablePoolMode<'a> {
1706    pub fn get_mode(&self) -> Result<&'a CStr, ErrorContext> {
1707        let mut iter = self.clone();
1708        iter.pos = 0;
1709        for attr in iter {
1710            if let Ok(PoolMode::Mode(val)) = attr {
1711                return Ok(val);
1712            }
1713        }
1714        Err(ErrorContext::new_missing(
1715            "PoolMode",
1716            "Mode",
1717            self.orig_loc,
1718            self.buf.as_ptr() as usize,
1719        ))
1720    }
1721    pub fn get_npools(&self) -> Result<u32, ErrorContext> {
1722        let mut iter = self.clone();
1723        iter.pos = 0;
1724        for attr in iter {
1725            if let Ok(PoolMode::Npools(val)) = attr {
1726                return Ok(val);
1727            }
1728        }
1729        Err(ErrorContext::new_missing(
1730            "PoolMode",
1731            "Npools",
1732            self.orig_loc,
1733            self.buf.as_ptr() as usize,
1734        ))
1735    }
1736}
1737impl PoolMode<'_> {
1738    pub fn new<'a>(buf: &'a [u8]) -> IterablePoolMode<'a> {
1739        IterablePoolMode::with_loc(buf, buf.as_ptr() as usize)
1740    }
1741    fn attr_from_type(r#type: u16) -> Option<&'static str> {
1742        let res = match r#type {
1743            1u16 => "Mode",
1744            2u16 => "Npools",
1745            _ => return None,
1746        };
1747        Some(res)
1748    }
1749}
1750#[derive(Clone, Copy, Default)]
1751pub struct IterablePoolMode<'a> {
1752    buf: &'a [u8],
1753    pos: usize,
1754    orig_loc: usize,
1755}
1756impl<'a> IterablePoolMode<'a> {
1757    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1758        Self {
1759            buf,
1760            pos: 0,
1761            orig_loc,
1762        }
1763    }
1764    pub fn get_buf(&self) -> &'a [u8] {
1765        self.buf
1766    }
1767}
1768impl<'a> Iterator for IterablePoolMode<'a> {
1769    type Item = Result<PoolMode<'a>, ErrorContext>;
1770    fn next(&mut self) -> Option<Self::Item> {
1771        let mut pos;
1772        let mut r#type;
1773        loop {
1774            pos = self.pos;
1775            r#type = None;
1776            if self.buf.len() == self.pos {
1777                return None;
1778            }
1779            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1780                self.pos = self.buf.len();
1781                break;
1782            };
1783            r#type = Some(header.r#type);
1784            let res = match header.r#type {
1785                1u16 => PoolMode::Mode({
1786                    let res = CStr::from_bytes_with_nul(next).ok();
1787                    let Some(val) = res else { break };
1788                    val
1789                }),
1790                2u16 => PoolMode::Npools({
1791                    let res = parse_u32(next);
1792                    let Some(val) = res else { break };
1793                    val
1794                }),
1795                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1796                n => continue,
1797            };
1798            return Some(Ok(res));
1799        }
1800        Some(Err(ErrorContext::new(
1801            "PoolMode",
1802            r#type.and_then(|t| PoolMode::attr_from_type(t)),
1803            self.orig_loc,
1804            self.buf.as_ptr().wrapping_add(pos) as usize,
1805        )))
1806    }
1807}
1808impl<'a> std::fmt::Debug for IterablePoolMode<'_> {
1809    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1810        let mut fmt = f.debug_struct("PoolMode");
1811        for attr in self.clone() {
1812            let attr = match attr {
1813                Ok(a) => a,
1814                Err(err) => {
1815                    fmt.finish()?;
1816                    f.write_str("Err(")?;
1817                    err.fmt(f)?;
1818                    return f.write_str(")");
1819                }
1820            };
1821            match attr {
1822                PoolMode::Mode(val) => fmt.field("Mode", &val),
1823                PoolMode::Npools(val) => fmt.field("Npools", &val),
1824            };
1825        }
1826        fmt.finish()
1827    }
1828}
1829impl IterablePoolMode<'_> {
1830    pub fn lookup_attr(
1831        &self,
1832        offset: usize,
1833        missing_type: Option<u16>,
1834    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1835        let mut stack = Vec::new();
1836        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1837        if missing_type.is_some() && cur == offset {
1838            stack.push(("PoolMode", offset));
1839            return (
1840                stack,
1841                missing_type.and_then(|t| PoolMode::attr_from_type(t)),
1842            );
1843        }
1844        if cur > offset || cur + self.buf.len() < offset {
1845            return (stack, None);
1846        }
1847        let mut attrs = self.clone();
1848        let mut last_off = cur + attrs.pos;
1849        while let Some(attr) = attrs.next() {
1850            let Ok(attr) = attr else { break };
1851            match attr {
1852                PoolMode::Mode(val) => {
1853                    if last_off == offset {
1854                        stack.push(("Mode", last_off));
1855                        break;
1856                    }
1857                }
1858                PoolMode::Npools(val) => {
1859                    if last_off == offset {
1860                        stack.push(("Npools", last_off));
1861                        break;
1862                    }
1863                }
1864                _ => {}
1865            };
1866            last_off = cur + attrs.pos;
1867        }
1868        if !stack.is_empty() {
1869            stack.push(("PoolMode", cur));
1870        }
1871        (stack, None)
1872    }
1873}
1874#[derive(Clone)]
1875pub enum Fslocation<'a> {
1876    Host(&'a CStr),
1877    Path(&'a CStr),
1878}
1879impl<'a> IterableFslocation<'a> {
1880    pub fn get_host(&self) -> Result<&'a CStr, ErrorContext> {
1881        let mut iter = self.clone();
1882        iter.pos = 0;
1883        for attr in iter {
1884            if let Ok(Fslocation::Host(val)) = attr {
1885                return Ok(val);
1886            }
1887        }
1888        Err(ErrorContext::new_missing(
1889            "Fslocation",
1890            "Host",
1891            self.orig_loc,
1892            self.buf.as_ptr() as usize,
1893        ))
1894    }
1895    pub fn get_path(&self) -> Result<&'a CStr, ErrorContext> {
1896        let mut iter = self.clone();
1897        iter.pos = 0;
1898        for attr in iter {
1899            if let Ok(Fslocation::Path(val)) = attr {
1900                return Ok(val);
1901            }
1902        }
1903        Err(ErrorContext::new_missing(
1904            "Fslocation",
1905            "Path",
1906            self.orig_loc,
1907            self.buf.as_ptr() as usize,
1908        ))
1909    }
1910}
1911impl Fslocation<'_> {
1912    pub fn new<'a>(buf: &'a [u8]) -> IterableFslocation<'a> {
1913        IterableFslocation::with_loc(buf, buf.as_ptr() as usize)
1914    }
1915    fn attr_from_type(r#type: u16) -> Option<&'static str> {
1916        let res = match r#type {
1917            1u16 => "Host",
1918            2u16 => "Path",
1919            _ => return None,
1920        };
1921        Some(res)
1922    }
1923}
1924#[derive(Clone, Copy, Default)]
1925pub struct IterableFslocation<'a> {
1926    buf: &'a [u8],
1927    pos: usize,
1928    orig_loc: usize,
1929}
1930impl<'a> IterableFslocation<'a> {
1931    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1932        Self {
1933            buf,
1934            pos: 0,
1935            orig_loc,
1936        }
1937    }
1938    pub fn get_buf(&self) -> &'a [u8] {
1939        self.buf
1940    }
1941}
1942impl<'a> Iterator for IterableFslocation<'a> {
1943    type Item = Result<Fslocation<'a>, ErrorContext>;
1944    fn next(&mut self) -> Option<Self::Item> {
1945        let mut pos;
1946        let mut r#type;
1947        loop {
1948            pos = self.pos;
1949            r#type = None;
1950            if self.buf.len() == self.pos {
1951                return None;
1952            }
1953            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1954                self.pos = self.buf.len();
1955                break;
1956            };
1957            r#type = Some(header.r#type);
1958            let res = match header.r#type {
1959                1u16 => Fslocation::Host({
1960                    let res = CStr::from_bytes_with_nul(next).ok();
1961                    let Some(val) = res else { break };
1962                    val
1963                }),
1964                2u16 => Fslocation::Path({
1965                    let res = CStr::from_bytes_with_nul(next).ok();
1966                    let Some(val) = res else { break };
1967                    val
1968                }),
1969                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1970                n => continue,
1971            };
1972            return Some(Ok(res));
1973        }
1974        Some(Err(ErrorContext::new(
1975            "Fslocation",
1976            r#type.and_then(|t| Fslocation::attr_from_type(t)),
1977            self.orig_loc,
1978            self.buf.as_ptr().wrapping_add(pos) as usize,
1979        )))
1980    }
1981}
1982impl<'a> std::fmt::Debug for IterableFslocation<'_> {
1983    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1984        let mut fmt = f.debug_struct("Fslocation");
1985        for attr in self.clone() {
1986            let attr = match attr {
1987                Ok(a) => a,
1988                Err(err) => {
1989                    fmt.finish()?;
1990                    f.write_str("Err(")?;
1991                    err.fmt(f)?;
1992                    return f.write_str(")");
1993                }
1994            };
1995            match attr {
1996                Fslocation::Host(val) => fmt.field("Host", &val),
1997                Fslocation::Path(val) => fmt.field("Path", &val),
1998            };
1999        }
2000        fmt.finish()
2001    }
2002}
2003impl IterableFslocation<'_> {
2004    pub fn lookup_attr(
2005        &self,
2006        offset: usize,
2007        missing_type: Option<u16>,
2008    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2009        let mut stack = Vec::new();
2010        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
2011        if missing_type.is_some() && cur == offset {
2012            stack.push(("Fslocation", offset));
2013            return (
2014                stack,
2015                missing_type.and_then(|t| Fslocation::attr_from_type(t)),
2016            );
2017        }
2018        if cur > offset || cur + self.buf.len() < offset {
2019            return (stack, None);
2020        }
2021        let mut attrs = self.clone();
2022        let mut last_off = cur + attrs.pos;
2023        while let Some(attr) = attrs.next() {
2024            let Ok(attr) = attr else { break };
2025            match attr {
2026                Fslocation::Host(val) => {
2027                    if last_off == offset {
2028                        stack.push(("Host", last_off));
2029                        break;
2030                    }
2031                }
2032                Fslocation::Path(val) => {
2033                    if last_off == offset {
2034                        stack.push(("Path", last_off));
2035                        break;
2036                    }
2037                }
2038                _ => {}
2039            };
2040            last_off = cur + attrs.pos;
2041        }
2042        if !stack.is_empty() {
2043            stack.push(("Fslocation", cur));
2044        }
2045        (stack, None)
2046    }
2047}
2048#[derive(Clone)]
2049pub enum Fslocations<'a> {
2050    #[doc = "Attribute may repeat multiple times (treat it as array)"]
2051    Location(IterableFslocation<'a>),
2052}
2053impl<'a> IterableFslocations<'a> {
2054    #[doc = "Attribute may repeat multiple times (treat it as array)"]
2055    pub fn get_location(&self) -> MultiAttrIterable<Self, Fslocations<'a>, IterableFslocation<'a>> {
2056        MultiAttrIterable::new(self.clone(), |variant| {
2057            if let Fslocations::Location(val) = variant {
2058                Some(val)
2059            } else {
2060                None
2061            }
2062        })
2063    }
2064}
2065impl Fslocations<'_> {
2066    pub fn new<'a>(buf: &'a [u8]) -> IterableFslocations<'a> {
2067        IterableFslocations::with_loc(buf, buf.as_ptr() as usize)
2068    }
2069    fn attr_from_type(r#type: u16) -> Option<&'static str> {
2070        let res = match r#type {
2071            1u16 => "Location",
2072            _ => return None,
2073        };
2074        Some(res)
2075    }
2076}
2077#[derive(Clone, Copy, Default)]
2078pub struct IterableFslocations<'a> {
2079    buf: &'a [u8],
2080    pos: usize,
2081    orig_loc: usize,
2082}
2083impl<'a> IterableFslocations<'a> {
2084    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2085        Self {
2086            buf,
2087            pos: 0,
2088            orig_loc,
2089        }
2090    }
2091    pub fn get_buf(&self) -> &'a [u8] {
2092        self.buf
2093    }
2094}
2095impl<'a> Iterator for IterableFslocations<'a> {
2096    type Item = Result<Fslocations<'a>, ErrorContext>;
2097    fn next(&mut self) -> Option<Self::Item> {
2098        let mut pos;
2099        let mut r#type;
2100        loop {
2101            pos = self.pos;
2102            r#type = None;
2103            if self.buf.len() == self.pos {
2104                return None;
2105            }
2106            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
2107                self.pos = self.buf.len();
2108                break;
2109            };
2110            r#type = Some(header.r#type);
2111            let res = match header.r#type {
2112                1u16 => Fslocations::Location({
2113                    let res = Some(IterableFslocation::with_loc(next, self.orig_loc));
2114                    let Some(val) = res else { break };
2115                    val
2116                }),
2117                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
2118                n => continue,
2119            };
2120            return Some(Ok(res));
2121        }
2122        Some(Err(ErrorContext::new(
2123            "Fslocations",
2124            r#type.and_then(|t| Fslocations::attr_from_type(t)),
2125            self.orig_loc,
2126            self.buf.as_ptr().wrapping_add(pos) as usize,
2127        )))
2128    }
2129}
2130impl<'a> std::fmt::Debug for IterableFslocations<'_> {
2131    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2132        let mut fmt = f.debug_struct("Fslocations");
2133        for attr in self.clone() {
2134            let attr = match attr {
2135                Ok(a) => a,
2136                Err(err) => {
2137                    fmt.finish()?;
2138                    f.write_str("Err(")?;
2139                    err.fmt(f)?;
2140                    return f.write_str(")");
2141                }
2142            };
2143            match attr {
2144                Fslocations::Location(val) => fmt.field("Location", &val),
2145            };
2146        }
2147        fmt.finish()
2148    }
2149}
2150impl IterableFslocations<'_> {
2151    pub fn lookup_attr(
2152        &self,
2153        offset: usize,
2154        missing_type: Option<u16>,
2155    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2156        let mut stack = Vec::new();
2157        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
2158        if missing_type.is_some() && cur == offset {
2159            stack.push(("Fslocations", offset));
2160            return (
2161                stack,
2162                missing_type.and_then(|t| Fslocations::attr_from_type(t)),
2163            );
2164        }
2165        if cur > offset || cur + self.buf.len() < offset {
2166            return (stack, None);
2167        }
2168        let mut attrs = self.clone();
2169        let mut last_off = cur + attrs.pos;
2170        let mut missing = None;
2171        while let Some(attr) = attrs.next() {
2172            let Ok(attr) = attr else { break };
2173            match attr {
2174                Fslocations::Location(val) => {
2175                    (stack, missing) = val.lookup_attr(offset, missing_type);
2176                    if !stack.is_empty() {
2177                        break;
2178                    }
2179                }
2180                _ => {}
2181            };
2182            last_off = cur + attrs.pos;
2183        }
2184        if !stack.is_empty() {
2185            stack.push(("Fslocations", cur));
2186        }
2187        (stack, missing)
2188    }
2189}
2190#[derive(Clone)]
2191pub enum AuthFlavor {
2192    Pseudoflavor(u32),
2193    #[doc = "Associated type: [`ExportFlags`] (1 bit per enumeration)"]
2194    Flags(u32),
2195}
2196impl<'a> IterableAuthFlavor<'a> {
2197    pub fn get_pseudoflavor(&self) -> Result<u32, ErrorContext> {
2198        let mut iter = self.clone();
2199        iter.pos = 0;
2200        for attr in iter {
2201            if let Ok(AuthFlavor::Pseudoflavor(val)) = attr {
2202                return Ok(val);
2203            }
2204        }
2205        Err(ErrorContext::new_missing(
2206            "AuthFlavor",
2207            "Pseudoflavor",
2208            self.orig_loc,
2209            self.buf.as_ptr() as usize,
2210        ))
2211    }
2212    #[doc = "Associated type: [`ExportFlags`] (1 bit per enumeration)"]
2213    pub fn get_flags(&self) -> Result<u32, ErrorContext> {
2214        let mut iter = self.clone();
2215        iter.pos = 0;
2216        for attr in iter {
2217            if let Ok(AuthFlavor::Flags(val)) = attr {
2218                return Ok(val);
2219            }
2220        }
2221        Err(ErrorContext::new_missing(
2222            "AuthFlavor",
2223            "Flags",
2224            self.orig_loc,
2225            self.buf.as_ptr() as usize,
2226        ))
2227    }
2228}
2229impl AuthFlavor {
2230    pub fn new<'a>(buf: &'a [u8]) -> IterableAuthFlavor<'a> {
2231        IterableAuthFlavor::with_loc(buf, buf.as_ptr() as usize)
2232    }
2233    fn attr_from_type(r#type: u16) -> Option<&'static str> {
2234        let res = match r#type {
2235            1u16 => "Pseudoflavor",
2236            2u16 => "Flags",
2237            _ => return None,
2238        };
2239        Some(res)
2240    }
2241}
2242#[derive(Clone, Copy, Default)]
2243pub struct IterableAuthFlavor<'a> {
2244    buf: &'a [u8],
2245    pos: usize,
2246    orig_loc: usize,
2247}
2248impl<'a> IterableAuthFlavor<'a> {
2249    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2250        Self {
2251            buf,
2252            pos: 0,
2253            orig_loc,
2254        }
2255    }
2256    pub fn get_buf(&self) -> &'a [u8] {
2257        self.buf
2258    }
2259}
2260impl<'a> Iterator for IterableAuthFlavor<'a> {
2261    type Item = Result<AuthFlavor, ErrorContext>;
2262    fn next(&mut self) -> Option<Self::Item> {
2263        let mut pos;
2264        let mut r#type;
2265        loop {
2266            pos = self.pos;
2267            r#type = None;
2268            if self.buf.len() == self.pos {
2269                return None;
2270            }
2271            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
2272                self.pos = self.buf.len();
2273                break;
2274            };
2275            r#type = Some(header.r#type);
2276            let res = match header.r#type {
2277                1u16 => AuthFlavor::Pseudoflavor({
2278                    let res = parse_u32(next);
2279                    let Some(val) = res else { break };
2280                    val
2281                }),
2282                2u16 => AuthFlavor::Flags({
2283                    let res = parse_u32(next);
2284                    let Some(val) = res else { break };
2285                    val
2286                }),
2287                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
2288                n => continue,
2289            };
2290            return Some(Ok(res));
2291        }
2292        Some(Err(ErrorContext::new(
2293            "AuthFlavor",
2294            r#type.and_then(|t| AuthFlavor::attr_from_type(t)),
2295            self.orig_loc,
2296            self.buf.as_ptr().wrapping_add(pos) as usize,
2297        )))
2298    }
2299}
2300impl std::fmt::Debug for IterableAuthFlavor<'_> {
2301    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2302        let mut fmt = f.debug_struct("AuthFlavor");
2303        for attr in self.clone() {
2304            let attr = match attr {
2305                Ok(a) => a,
2306                Err(err) => {
2307                    fmt.finish()?;
2308                    f.write_str("Err(")?;
2309                    err.fmt(f)?;
2310                    return f.write_str(")");
2311                }
2312            };
2313            match attr {
2314                AuthFlavor::Pseudoflavor(val) => fmt.field("Pseudoflavor", &val),
2315                AuthFlavor::Flags(val) => {
2316                    fmt.field("Flags", &FormatFlags(val.into(), ExportFlags::from_value))
2317                }
2318            };
2319        }
2320        fmt.finish()
2321    }
2322}
2323impl IterableAuthFlavor<'_> {
2324    pub fn lookup_attr(
2325        &self,
2326        offset: usize,
2327        missing_type: Option<u16>,
2328    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2329        let mut stack = Vec::new();
2330        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
2331        if missing_type.is_some() && cur == offset {
2332            stack.push(("AuthFlavor", offset));
2333            return (
2334                stack,
2335                missing_type.and_then(|t| AuthFlavor::attr_from_type(t)),
2336            );
2337        }
2338        if cur > offset || cur + self.buf.len() < offset {
2339            return (stack, None);
2340        }
2341        let mut attrs = self.clone();
2342        let mut last_off = cur + attrs.pos;
2343        while let Some(attr) = attrs.next() {
2344            let Ok(attr) = attr else { break };
2345            match attr {
2346                AuthFlavor::Pseudoflavor(val) => {
2347                    if last_off == offset {
2348                        stack.push(("Pseudoflavor", last_off));
2349                        break;
2350                    }
2351                }
2352                AuthFlavor::Flags(val) => {
2353                    if last_off == offset {
2354                        stack.push(("Flags", last_off));
2355                        break;
2356                    }
2357                }
2358                _ => {}
2359            };
2360            last_off = cur + attrs.pos;
2361        }
2362        if !stack.is_empty() {
2363            stack.push(("AuthFlavor", cur));
2364        }
2365        (stack, None)
2366    }
2367}
2368#[derive(Clone)]
2369pub enum SvcExport<'a> {
2370    Seqno(u64),
2371    Client(&'a CStr),
2372    Path(&'a CStr),
2373    Negative(()),
2374    Expiry(u64),
2375    AnonUid(u32),
2376    AnonGid(u32),
2377    Fslocations(IterableFslocations<'a>),
2378    Uuid(&'a [u8]),
2379    #[doc = "Attribute may repeat multiple times (treat it as array)"]
2380    Secinfo(IterableAuthFlavor<'a>),
2381    #[doc = "Associated type: [`XprtsecMode`] (enum)\nAttribute may repeat multiple times (treat it as array)"]
2382    Xprtsec(u32),
2383    #[doc = "Associated type: [`ExportFlags`] (1 bit per enumeration)"]
2384    Flags(u32),
2385    Fsid(i32),
2386}
2387impl<'a> IterableSvcExport<'a> {
2388    pub fn get_seqno(&self) -> Result<u64, ErrorContext> {
2389        let mut iter = self.clone();
2390        iter.pos = 0;
2391        for attr in iter {
2392            if let Ok(SvcExport::Seqno(val)) = attr {
2393                return Ok(val);
2394            }
2395        }
2396        Err(ErrorContext::new_missing(
2397            "SvcExport",
2398            "Seqno",
2399            self.orig_loc,
2400            self.buf.as_ptr() as usize,
2401        ))
2402    }
2403    pub fn get_client(&self) -> Result<&'a CStr, ErrorContext> {
2404        let mut iter = self.clone();
2405        iter.pos = 0;
2406        for attr in iter {
2407            if let Ok(SvcExport::Client(val)) = attr {
2408                return Ok(val);
2409            }
2410        }
2411        Err(ErrorContext::new_missing(
2412            "SvcExport",
2413            "Client",
2414            self.orig_loc,
2415            self.buf.as_ptr() as usize,
2416        ))
2417    }
2418    pub fn get_path(&self) -> Result<&'a CStr, ErrorContext> {
2419        let mut iter = self.clone();
2420        iter.pos = 0;
2421        for attr in iter {
2422            if let Ok(SvcExport::Path(val)) = attr {
2423                return Ok(val);
2424            }
2425        }
2426        Err(ErrorContext::new_missing(
2427            "SvcExport",
2428            "Path",
2429            self.orig_loc,
2430            self.buf.as_ptr() as usize,
2431        ))
2432    }
2433    pub fn get_negative(&self) -> Result<(), ErrorContext> {
2434        let mut iter = self.clone();
2435        iter.pos = 0;
2436        for attr in iter {
2437            if let Ok(SvcExport::Negative(val)) = attr {
2438                return Ok(val);
2439            }
2440        }
2441        Err(ErrorContext::new_missing(
2442            "SvcExport",
2443            "Negative",
2444            self.orig_loc,
2445            self.buf.as_ptr() as usize,
2446        ))
2447    }
2448    pub fn get_expiry(&self) -> Result<u64, ErrorContext> {
2449        let mut iter = self.clone();
2450        iter.pos = 0;
2451        for attr in iter {
2452            if let Ok(SvcExport::Expiry(val)) = attr {
2453                return Ok(val);
2454            }
2455        }
2456        Err(ErrorContext::new_missing(
2457            "SvcExport",
2458            "Expiry",
2459            self.orig_loc,
2460            self.buf.as_ptr() as usize,
2461        ))
2462    }
2463    pub fn get_anon_uid(&self) -> Result<u32, ErrorContext> {
2464        let mut iter = self.clone();
2465        iter.pos = 0;
2466        for attr in iter {
2467            if let Ok(SvcExport::AnonUid(val)) = attr {
2468                return Ok(val);
2469            }
2470        }
2471        Err(ErrorContext::new_missing(
2472            "SvcExport",
2473            "AnonUid",
2474            self.orig_loc,
2475            self.buf.as_ptr() as usize,
2476        ))
2477    }
2478    pub fn get_anon_gid(&self) -> Result<u32, ErrorContext> {
2479        let mut iter = self.clone();
2480        iter.pos = 0;
2481        for attr in iter {
2482            if let Ok(SvcExport::AnonGid(val)) = attr {
2483                return Ok(val);
2484            }
2485        }
2486        Err(ErrorContext::new_missing(
2487            "SvcExport",
2488            "AnonGid",
2489            self.orig_loc,
2490            self.buf.as_ptr() as usize,
2491        ))
2492    }
2493    pub fn get_fslocations(&self) -> Result<IterableFslocations<'a>, ErrorContext> {
2494        let mut iter = self.clone();
2495        iter.pos = 0;
2496        for attr in iter {
2497            if let Ok(SvcExport::Fslocations(val)) = attr {
2498                return Ok(val);
2499            }
2500        }
2501        Err(ErrorContext::new_missing(
2502            "SvcExport",
2503            "Fslocations",
2504            self.orig_loc,
2505            self.buf.as_ptr() as usize,
2506        ))
2507    }
2508    pub fn get_uuid(&self) -> Result<&'a [u8], ErrorContext> {
2509        let mut iter = self.clone();
2510        iter.pos = 0;
2511        for attr in iter {
2512            if let Ok(SvcExport::Uuid(val)) = attr {
2513                return Ok(val);
2514            }
2515        }
2516        Err(ErrorContext::new_missing(
2517            "SvcExport",
2518            "Uuid",
2519            self.orig_loc,
2520            self.buf.as_ptr() as usize,
2521        ))
2522    }
2523    #[doc = "Attribute may repeat multiple times (treat it as array)"]
2524    pub fn get_secinfo(&self) -> MultiAttrIterable<Self, SvcExport<'a>, IterableAuthFlavor<'a>> {
2525        MultiAttrIterable::new(self.clone(), |variant| {
2526            if let SvcExport::Secinfo(val) = variant {
2527                Some(val)
2528            } else {
2529                None
2530            }
2531        })
2532    }
2533    #[doc = "Associated type: [`XprtsecMode`] (enum)\nAttribute may repeat multiple times (treat it as array)"]
2534    pub fn get_xprtsec(&self) -> MultiAttrIterable<Self, SvcExport<'a>, u32> {
2535        MultiAttrIterable::new(self.clone(), |variant| {
2536            if let SvcExport::Xprtsec(val) = variant {
2537                Some(val)
2538            } else {
2539                None
2540            }
2541        })
2542    }
2543    #[doc = "Associated type: [`ExportFlags`] (1 bit per enumeration)"]
2544    pub fn get_flags(&self) -> Result<u32, ErrorContext> {
2545        let mut iter = self.clone();
2546        iter.pos = 0;
2547        for attr in iter {
2548            if let Ok(SvcExport::Flags(val)) = attr {
2549                return Ok(val);
2550            }
2551        }
2552        Err(ErrorContext::new_missing(
2553            "SvcExport",
2554            "Flags",
2555            self.orig_loc,
2556            self.buf.as_ptr() as usize,
2557        ))
2558    }
2559    pub fn get_fsid(&self) -> Result<i32, ErrorContext> {
2560        let mut iter = self.clone();
2561        iter.pos = 0;
2562        for attr in iter {
2563            if let Ok(SvcExport::Fsid(val)) = attr {
2564                return Ok(val);
2565            }
2566        }
2567        Err(ErrorContext::new_missing(
2568            "SvcExport",
2569            "Fsid",
2570            self.orig_loc,
2571            self.buf.as_ptr() as usize,
2572        ))
2573    }
2574}
2575impl SvcExport<'_> {
2576    pub fn new<'a>(buf: &'a [u8]) -> IterableSvcExport<'a> {
2577        IterableSvcExport::with_loc(buf, buf.as_ptr() as usize)
2578    }
2579    fn attr_from_type(r#type: u16) -> Option<&'static str> {
2580        let res = match r#type {
2581            1u16 => "Seqno",
2582            2u16 => "Client",
2583            3u16 => "Path",
2584            4u16 => "Negative",
2585            5u16 => "Expiry",
2586            6u16 => "AnonUid",
2587            7u16 => "AnonGid",
2588            8u16 => "Fslocations",
2589            9u16 => "Uuid",
2590            10u16 => "Secinfo",
2591            11u16 => "Xprtsec",
2592            12u16 => "Flags",
2593            13u16 => "Fsid",
2594            _ => return None,
2595        };
2596        Some(res)
2597    }
2598}
2599#[derive(Clone, Copy, Default)]
2600pub struct IterableSvcExport<'a> {
2601    buf: &'a [u8],
2602    pos: usize,
2603    orig_loc: usize,
2604}
2605impl<'a> IterableSvcExport<'a> {
2606    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2607        Self {
2608            buf,
2609            pos: 0,
2610            orig_loc,
2611        }
2612    }
2613    pub fn get_buf(&self) -> &'a [u8] {
2614        self.buf
2615    }
2616}
2617impl<'a> Iterator for IterableSvcExport<'a> {
2618    type Item = Result<SvcExport<'a>, ErrorContext>;
2619    fn next(&mut self) -> Option<Self::Item> {
2620        let mut pos;
2621        let mut r#type;
2622        loop {
2623            pos = self.pos;
2624            r#type = None;
2625            if self.buf.len() == self.pos {
2626                return None;
2627            }
2628            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
2629                self.pos = self.buf.len();
2630                break;
2631            };
2632            r#type = Some(header.r#type);
2633            let res = match header.r#type {
2634                1u16 => SvcExport::Seqno({
2635                    let res = parse_u64(next);
2636                    let Some(val) = res else { break };
2637                    val
2638                }),
2639                2u16 => SvcExport::Client({
2640                    let res = CStr::from_bytes_with_nul(next).ok();
2641                    let Some(val) = res else { break };
2642                    val
2643                }),
2644                3u16 => SvcExport::Path({
2645                    let res = CStr::from_bytes_with_nul(next).ok();
2646                    let Some(val) = res else { break };
2647                    val
2648                }),
2649                4u16 => SvcExport::Negative(()),
2650                5u16 => SvcExport::Expiry({
2651                    let res = parse_u64(next);
2652                    let Some(val) = res else { break };
2653                    val
2654                }),
2655                6u16 => SvcExport::AnonUid({
2656                    let res = parse_u32(next);
2657                    let Some(val) = res else { break };
2658                    val
2659                }),
2660                7u16 => SvcExport::AnonGid({
2661                    let res = parse_u32(next);
2662                    let Some(val) = res else { break };
2663                    val
2664                }),
2665                8u16 => SvcExport::Fslocations({
2666                    let res = Some(IterableFslocations::with_loc(next, self.orig_loc));
2667                    let Some(val) = res else { break };
2668                    val
2669                }),
2670                9u16 => SvcExport::Uuid({
2671                    let res = Some(next);
2672                    let Some(val) = res else { break };
2673                    val
2674                }),
2675                10u16 => SvcExport::Secinfo({
2676                    let res = Some(IterableAuthFlavor::with_loc(next, self.orig_loc));
2677                    let Some(val) = res else { break };
2678                    val
2679                }),
2680                11u16 => SvcExport::Xprtsec({
2681                    let res = parse_u32(next);
2682                    let Some(val) = res else { break };
2683                    val
2684                }),
2685                12u16 => SvcExport::Flags({
2686                    let res = parse_u32(next);
2687                    let Some(val) = res else { break };
2688                    val
2689                }),
2690                13u16 => SvcExport::Fsid({
2691                    let res = parse_i32(next);
2692                    let Some(val) = res else { break };
2693                    val
2694                }),
2695                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
2696                n => continue,
2697            };
2698            return Some(Ok(res));
2699        }
2700        Some(Err(ErrorContext::new(
2701            "SvcExport",
2702            r#type.and_then(|t| SvcExport::attr_from_type(t)),
2703            self.orig_loc,
2704            self.buf.as_ptr().wrapping_add(pos) as usize,
2705        )))
2706    }
2707}
2708impl<'a> std::fmt::Debug for IterableSvcExport<'_> {
2709    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2710        let mut fmt = f.debug_struct("SvcExport");
2711        for attr in self.clone() {
2712            let attr = match attr {
2713                Ok(a) => a,
2714                Err(err) => {
2715                    fmt.finish()?;
2716                    f.write_str("Err(")?;
2717                    err.fmt(f)?;
2718                    return f.write_str(")");
2719                }
2720            };
2721            match attr {
2722                SvcExport::Seqno(val) => fmt.field("Seqno", &val),
2723                SvcExport::Client(val) => fmt.field("Client", &val),
2724                SvcExport::Path(val) => fmt.field("Path", &val),
2725                SvcExport::Negative(val) => fmt.field("Negative", &val),
2726                SvcExport::Expiry(val) => fmt.field("Expiry", &val),
2727                SvcExport::AnonUid(val) => fmt.field("AnonUid", &val),
2728                SvcExport::AnonGid(val) => fmt.field("AnonGid", &val),
2729                SvcExport::Fslocations(val) => fmt.field("Fslocations", &val),
2730                SvcExport::Uuid(val) => fmt.field("Uuid", &val),
2731                SvcExport::Secinfo(val) => fmt.field("Secinfo", &val),
2732                SvcExport::Xprtsec(val) => {
2733                    fmt.field("Xprtsec", &FormatFlags(val.into(), XprtsecMode::from_value))
2734                }
2735                SvcExport::Flags(val) => {
2736                    fmt.field("Flags", &FormatFlags(val.into(), ExportFlags::from_value))
2737                }
2738                SvcExport::Fsid(val) => fmt.field("Fsid", &val),
2739            };
2740        }
2741        fmt.finish()
2742    }
2743}
2744impl IterableSvcExport<'_> {
2745    pub fn lookup_attr(
2746        &self,
2747        offset: usize,
2748        missing_type: Option<u16>,
2749    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2750        let mut stack = Vec::new();
2751        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
2752        if missing_type.is_some() && cur == offset {
2753            stack.push(("SvcExport", offset));
2754            return (
2755                stack,
2756                missing_type.and_then(|t| SvcExport::attr_from_type(t)),
2757            );
2758        }
2759        if cur > offset || cur + self.buf.len() < offset {
2760            return (stack, None);
2761        }
2762        let mut attrs = self.clone();
2763        let mut last_off = cur + attrs.pos;
2764        let mut missing = None;
2765        while let Some(attr) = attrs.next() {
2766            let Ok(attr) = attr else { break };
2767            match attr {
2768                SvcExport::Seqno(val) => {
2769                    if last_off == offset {
2770                        stack.push(("Seqno", last_off));
2771                        break;
2772                    }
2773                }
2774                SvcExport::Client(val) => {
2775                    if last_off == offset {
2776                        stack.push(("Client", last_off));
2777                        break;
2778                    }
2779                }
2780                SvcExport::Path(val) => {
2781                    if last_off == offset {
2782                        stack.push(("Path", last_off));
2783                        break;
2784                    }
2785                }
2786                SvcExport::Negative(val) => {
2787                    if last_off == offset {
2788                        stack.push(("Negative", last_off));
2789                        break;
2790                    }
2791                }
2792                SvcExport::Expiry(val) => {
2793                    if last_off == offset {
2794                        stack.push(("Expiry", last_off));
2795                        break;
2796                    }
2797                }
2798                SvcExport::AnonUid(val) => {
2799                    if last_off == offset {
2800                        stack.push(("AnonUid", last_off));
2801                        break;
2802                    }
2803                }
2804                SvcExport::AnonGid(val) => {
2805                    if last_off == offset {
2806                        stack.push(("AnonGid", last_off));
2807                        break;
2808                    }
2809                }
2810                SvcExport::Fslocations(val) => {
2811                    (stack, missing) = val.lookup_attr(offset, missing_type);
2812                    if !stack.is_empty() {
2813                        break;
2814                    }
2815                }
2816                SvcExport::Uuid(val) => {
2817                    if last_off == offset {
2818                        stack.push(("Uuid", last_off));
2819                        break;
2820                    }
2821                }
2822                SvcExport::Secinfo(val) => {
2823                    (stack, missing) = val.lookup_attr(offset, missing_type);
2824                    if !stack.is_empty() {
2825                        break;
2826                    }
2827                }
2828                SvcExport::Xprtsec(val) => {
2829                    if last_off == offset {
2830                        stack.push(("Xprtsec", last_off));
2831                        break;
2832                    }
2833                }
2834                SvcExport::Flags(val) => {
2835                    if last_off == offset {
2836                        stack.push(("Flags", last_off));
2837                        break;
2838                    }
2839                }
2840                SvcExport::Fsid(val) => {
2841                    if last_off == offset {
2842                        stack.push(("Fsid", last_off));
2843                        break;
2844                    }
2845                }
2846                _ => {}
2847            };
2848            last_off = cur + attrs.pos;
2849        }
2850        if !stack.is_empty() {
2851            stack.push(("SvcExport", cur));
2852        }
2853        (stack, missing)
2854    }
2855}
2856#[derive(Clone)]
2857pub enum SvcExportReqs<'a> {
2858    #[doc = "Attribute may repeat multiple times (treat it as array)"]
2859    Requests(IterableSvcExport<'a>),
2860}
2861impl<'a> IterableSvcExportReqs<'a> {
2862    #[doc = "Attribute may repeat multiple times (treat it as array)"]
2863    pub fn get_requests(
2864        &self,
2865    ) -> MultiAttrIterable<Self, SvcExportReqs<'a>, IterableSvcExport<'a>> {
2866        MultiAttrIterable::new(self.clone(), |variant| {
2867            if let SvcExportReqs::Requests(val) = variant {
2868                Some(val)
2869            } else {
2870                None
2871            }
2872        })
2873    }
2874}
2875impl SvcExportReqs<'_> {
2876    pub fn new<'a>(buf: &'a [u8]) -> IterableSvcExportReqs<'a> {
2877        IterableSvcExportReqs::with_loc(buf, buf.as_ptr() as usize)
2878    }
2879    fn attr_from_type(r#type: u16) -> Option<&'static str> {
2880        let res = match r#type {
2881            1u16 => "Requests",
2882            _ => return None,
2883        };
2884        Some(res)
2885    }
2886}
2887#[derive(Clone, Copy, Default)]
2888pub struct IterableSvcExportReqs<'a> {
2889    buf: &'a [u8],
2890    pos: usize,
2891    orig_loc: usize,
2892}
2893impl<'a> IterableSvcExportReqs<'a> {
2894    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2895        Self {
2896            buf,
2897            pos: 0,
2898            orig_loc,
2899        }
2900    }
2901    pub fn get_buf(&self) -> &'a [u8] {
2902        self.buf
2903    }
2904}
2905impl<'a> Iterator for IterableSvcExportReqs<'a> {
2906    type Item = Result<SvcExportReqs<'a>, ErrorContext>;
2907    fn next(&mut self) -> Option<Self::Item> {
2908        let mut pos;
2909        let mut r#type;
2910        loop {
2911            pos = self.pos;
2912            r#type = None;
2913            if self.buf.len() == self.pos {
2914                return None;
2915            }
2916            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
2917                self.pos = self.buf.len();
2918                break;
2919            };
2920            r#type = Some(header.r#type);
2921            let res = match header.r#type {
2922                1u16 => SvcExportReqs::Requests({
2923                    let res = Some(IterableSvcExport::with_loc(next, self.orig_loc));
2924                    let Some(val) = res else { break };
2925                    val
2926                }),
2927                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
2928                n => continue,
2929            };
2930            return Some(Ok(res));
2931        }
2932        Some(Err(ErrorContext::new(
2933            "SvcExportReqs",
2934            r#type.and_then(|t| SvcExportReqs::attr_from_type(t)),
2935            self.orig_loc,
2936            self.buf.as_ptr().wrapping_add(pos) as usize,
2937        )))
2938    }
2939}
2940impl<'a> std::fmt::Debug for IterableSvcExportReqs<'_> {
2941    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2942        let mut fmt = f.debug_struct("SvcExportReqs");
2943        for attr in self.clone() {
2944            let attr = match attr {
2945                Ok(a) => a,
2946                Err(err) => {
2947                    fmt.finish()?;
2948                    f.write_str("Err(")?;
2949                    err.fmt(f)?;
2950                    return f.write_str(")");
2951                }
2952            };
2953            match attr {
2954                SvcExportReqs::Requests(val) => fmt.field("Requests", &val),
2955            };
2956        }
2957        fmt.finish()
2958    }
2959}
2960impl IterableSvcExportReqs<'_> {
2961    pub fn lookup_attr(
2962        &self,
2963        offset: usize,
2964        missing_type: Option<u16>,
2965    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2966        let mut stack = Vec::new();
2967        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
2968        if missing_type.is_some() && cur == offset {
2969            stack.push(("SvcExportReqs", offset));
2970            return (
2971                stack,
2972                missing_type.and_then(|t| SvcExportReqs::attr_from_type(t)),
2973            );
2974        }
2975        if cur > offset || cur + self.buf.len() < offset {
2976            return (stack, None);
2977        }
2978        let mut attrs = self.clone();
2979        let mut last_off = cur + attrs.pos;
2980        let mut missing = None;
2981        while let Some(attr) = attrs.next() {
2982            let Ok(attr) = attr else { break };
2983            match attr {
2984                SvcExportReqs::Requests(val) => {
2985                    (stack, missing) = val.lookup_attr(offset, missing_type);
2986                    if !stack.is_empty() {
2987                        break;
2988                    }
2989                }
2990                _ => {}
2991            };
2992            last_off = cur + attrs.pos;
2993        }
2994        if !stack.is_empty() {
2995            stack.push(("SvcExportReqs", cur));
2996        }
2997        (stack, missing)
2998    }
2999}
3000#[derive(Clone)]
3001pub enum Expkey<'a> {
3002    Seqno(u64),
3003    Client(&'a CStr),
3004    Fsidtype(u8),
3005    Fsid(&'a [u8]),
3006    Negative(()),
3007    Expiry(u64),
3008    Path(&'a CStr),
3009}
3010impl<'a> IterableExpkey<'a> {
3011    pub fn get_seqno(&self) -> Result<u64, ErrorContext> {
3012        let mut iter = self.clone();
3013        iter.pos = 0;
3014        for attr in iter {
3015            if let Ok(Expkey::Seqno(val)) = attr {
3016                return Ok(val);
3017            }
3018        }
3019        Err(ErrorContext::new_missing(
3020            "Expkey",
3021            "Seqno",
3022            self.orig_loc,
3023            self.buf.as_ptr() as usize,
3024        ))
3025    }
3026    pub fn get_client(&self) -> Result<&'a CStr, ErrorContext> {
3027        let mut iter = self.clone();
3028        iter.pos = 0;
3029        for attr in iter {
3030            if let Ok(Expkey::Client(val)) = attr {
3031                return Ok(val);
3032            }
3033        }
3034        Err(ErrorContext::new_missing(
3035            "Expkey",
3036            "Client",
3037            self.orig_loc,
3038            self.buf.as_ptr() as usize,
3039        ))
3040    }
3041    pub fn get_fsidtype(&self) -> Result<u8, ErrorContext> {
3042        let mut iter = self.clone();
3043        iter.pos = 0;
3044        for attr in iter {
3045            if let Ok(Expkey::Fsidtype(val)) = attr {
3046                return Ok(val);
3047            }
3048        }
3049        Err(ErrorContext::new_missing(
3050            "Expkey",
3051            "Fsidtype",
3052            self.orig_loc,
3053            self.buf.as_ptr() as usize,
3054        ))
3055    }
3056    pub fn get_fsid(&self) -> Result<&'a [u8], ErrorContext> {
3057        let mut iter = self.clone();
3058        iter.pos = 0;
3059        for attr in iter {
3060            if let Ok(Expkey::Fsid(val)) = attr {
3061                return Ok(val);
3062            }
3063        }
3064        Err(ErrorContext::new_missing(
3065            "Expkey",
3066            "Fsid",
3067            self.orig_loc,
3068            self.buf.as_ptr() as usize,
3069        ))
3070    }
3071    pub fn get_negative(&self) -> Result<(), ErrorContext> {
3072        let mut iter = self.clone();
3073        iter.pos = 0;
3074        for attr in iter {
3075            if let Ok(Expkey::Negative(val)) = attr {
3076                return Ok(val);
3077            }
3078        }
3079        Err(ErrorContext::new_missing(
3080            "Expkey",
3081            "Negative",
3082            self.orig_loc,
3083            self.buf.as_ptr() as usize,
3084        ))
3085    }
3086    pub fn get_expiry(&self) -> Result<u64, ErrorContext> {
3087        let mut iter = self.clone();
3088        iter.pos = 0;
3089        for attr in iter {
3090            if let Ok(Expkey::Expiry(val)) = attr {
3091                return Ok(val);
3092            }
3093        }
3094        Err(ErrorContext::new_missing(
3095            "Expkey",
3096            "Expiry",
3097            self.orig_loc,
3098            self.buf.as_ptr() as usize,
3099        ))
3100    }
3101    pub fn get_path(&self) -> Result<&'a CStr, ErrorContext> {
3102        let mut iter = self.clone();
3103        iter.pos = 0;
3104        for attr in iter {
3105            if let Ok(Expkey::Path(val)) = attr {
3106                return Ok(val);
3107            }
3108        }
3109        Err(ErrorContext::new_missing(
3110            "Expkey",
3111            "Path",
3112            self.orig_loc,
3113            self.buf.as_ptr() as usize,
3114        ))
3115    }
3116}
3117impl Expkey<'_> {
3118    pub fn new<'a>(buf: &'a [u8]) -> IterableExpkey<'a> {
3119        IterableExpkey::with_loc(buf, buf.as_ptr() as usize)
3120    }
3121    fn attr_from_type(r#type: u16) -> Option<&'static str> {
3122        let res = match r#type {
3123            1u16 => "Seqno",
3124            2u16 => "Client",
3125            3u16 => "Fsidtype",
3126            4u16 => "Fsid",
3127            5u16 => "Negative",
3128            6u16 => "Expiry",
3129            7u16 => "Path",
3130            _ => return None,
3131        };
3132        Some(res)
3133    }
3134}
3135#[derive(Clone, Copy, Default)]
3136pub struct IterableExpkey<'a> {
3137    buf: &'a [u8],
3138    pos: usize,
3139    orig_loc: usize,
3140}
3141impl<'a> IterableExpkey<'a> {
3142    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3143        Self {
3144            buf,
3145            pos: 0,
3146            orig_loc,
3147        }
3148    }
3149    pub fn get_buf(&self) -> &'a [u8] {
3150        self.buf
3151    }
3152}
3153impl<'a> Iterator for IterableExpkey<'a> {
3154    type Item = Result<Expkey<'a>, ErrorContext>;
3155    fn next(&mut self) -> Option<Self::Item> {
3156        let mut pos;
3157        let mut r#type;
3158        loop {
3159            pos = self.pos;
3160            r#type = None;
3161            if self.buf.len() == self.pos {
3162                return None;
3163            }
3164            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
3165                self.pos = self.buf.len();
3166                break;
3167            };
3168            r#type = Some(header.r#type);
3169            let res = match header.r#type {
3170                1u16 => Expkey::Seqno({
3171                    let res = parse_u64(next);
3172                    let Some(val) = res else { break };
3173                    val
3174                }),
3175                2u16 => Expkey::Client({
3176                    let res = CStr::from_bytes_with_nul(next).ok();
3177                    let Some(val) = res else { break };
3178                    val
3179                }),
3180                3u16 => Expkey::Fsidtype({
3181                    let res = parse_u8(next);
3182                    let Some(val) = res else { break };
3183                    val
3184                }),
3185                4u16 => Expkey::Fsid({
3186                    let res = Some(next);
3187                    let Some(val) = res else { break };
3188                    val
3189                }),
3190                5u16 => Expkey::Negative(()),
3191                6u16 => Expkey::Expiry({
3192                    let res = parse_u64(next);
3193                    let Some(val) = res else { break };
3194                    val
3195                }),
3196                7u16 => Expkey::Path({
3197                    let res = CStr::from_bytes_with_nul(next).ok();
3198                    let Some(val) = res else { break };
3199                    val
3200                }),
3201                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
3202                n => continue,
3203            };
3204            return Some(Ok(res));
3205        }
3206        Some(Err(ErrorContext::new(
3207            "Expkey",
3208            r#type.and_then(|t| Expkey::attr_from_type(t)),
3209            self.orig_loc,
3210            self.buf.as_ptr().wrapping_add(pos) as usize,
3211        )))
3212    }
3213}
3214impl<'a> std::fmt::Debug for IterableExpkey<'_> {
3215    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3216        let mut fmt = f.debug_struct("Expkey");
3217        for attr in self.clone() {
3218            let attr = match attr {
3219                Ok(a) => a,
3220                Err(err) => {
3221                    fmt.finish()?;
3222                    f.write_str("Err(")?;
3223                    err.fmt(f)?;
3224                    return f.write_str(")");
3225                }
3226            };
3227            match attr {
3228                Expkey::Seqno(val) => fmt.field("Seqno", &val),
3229                Expkey::Client(val) => fmt.field("Client", &val),
3230                Expkey::Fsidtype(val) => fmt.field("Fsidtype", &val),
3231                Expkey::Fsid(val) => fmt.field("Fsid", &val),
3232                Expkey::Negative(val) => fmt.field("Negative", &val),
3233                Expkey::Expiry(val) => fmt.field("Expiry", &val),
3234                Expkey::Path(val) => fmt.field("Path", &val),
3235            };
3236        }
3237        fmt.finish()
3238    }
3239}
3240impl IterableExpkey<'_> {
3241    pub fn lookup_attr(
3242        &self,
3243        offset: usize,
3244        missing_type: Option<u16>,
3245    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3246        let mut stack = Vec::new();
3247        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3248        if missing_type.is_some() && cur == offset {
3249            stack.push(("Expkey", offset));
3250            return (stack, missing_type.and_then(|t| Expkey::attr_from_type(t)));
3251        }
3252        if cur > offset || cur + self.buf.len() < offset {
3253            return (stack, None);
3254        }
3255        let mut attrs = self.clone();
3256        let mut last_off = cur + attrs.pos;
3257        while let Some(attr) = attrs.next() {
3258            let Ok(attr) = attr else { break };
3259            match attr {
3260                Expkey::Seqno(val) => {
3261                    if last_off == offset {
3262                        stack.push(("Seqno", last_off));
3263                        break;
3264                    }
3265                }
3266                Expkey::Client(val) => {
3267                    if last_off == offset {
3268                        stack.push(("Client", last_off));
3269                        break;
3270                    }
3271                }
3272                Expkey::Fsidtype(val) => {
3273                    if last_off == offset {
3274                        stack.push(("Fsidtype", last_off));
3275                        break;
3276                    }
3277                }
3278                Expkey::Fsid(val) => {
3279                    if last_off == offset {
3280                        stack.push(("Fsid", last_off));
3281                        break;
3282                    }
3283                }
3284                Expkey::Negative(val) => {
3285                    if last_off == offset {
3286                        stack.push(("Negative", last_off));
3287                        break;
3288                    }
3289                }
3290                Expkey::Expiry(val) => {
3291                    if last_off == offset {
3292                        stack.push(("Expiry", last_off));
3293                        break;
3294                    }
3295                }
3296                Expkey::Path(val) => {
3297                    if last_off == offset {
3298                        stack.push(("Path", last_off));
3299                        break;
3300                    }
3301                }
3302                _ => {}
3303            };
3304            last_off = cur + attrs.pos;
3305        }
3306        if !stack.is_empty() {
3307            stack.push(("Expkey", cur));
3308        }
3309        (stack, None)
3310    }
3311}
3312#[derive(Clone)]
3313pub enum ExpkeyReqs<'a> {
3314    #[doc = "Attribute may repeat multiple times (treat it as array)"]
3315    Requests(IterableExpkey<'a>),
3316}
3317impl<'a> IterableExpkeyReqs<'a> {
3318    #[doc = "Attribute may repeat multiple times (treat it as array)"]
3319    pub fn get_requests(&self) -> MultiAttrIterable<Self, ExpkeyReqs<'a>, IterableExpkey<'a>> {
3320        MultiAttrIterable::new(self.clone(), |variant| {
3321            if let ExpkeyReqs::Requests(val) = variant {
3322                Some(val)
3323            } else {
3324                None
3325            }
3326        })
3327    }
3328}
3329impl ExpkeyReqs<'_> {
3330    pub fn new<'a>(buf: &'a [u8]) -> IterableExpkeyReqs<'a> {
3331        IterableExpkeyReqs::with_loc(buf, buf.as_ptr() as usize)
3332    }
3333    fn attr_from_type(r#type: u16) -> Option<&'static str> {
3334        let res = match r#type {
3335            1u16 => "Requests",
3336            _ => return None,
3337        };
3338        Some(res)
3339    }
3340}
3341#[derive(Clone, Copy, Default)]
3342pub struct IterableExpkeyReqs<'a> {
3343    buf: &'a [u8],
3344    pos: usize,
3345    orig_loc: usize,
3346}
3347impl<'a> IterableExpkeyReqs<'a> {
3348    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3349        Self {
3350            buf,
3351            pos: 0,
3352            orig_loc,
3353        }
3354    }
3355    pub fn get_buf(&self) -> &'a [u8] {
3356        self.buf
3357    }
3358}
3359impl<'a> Iterator for IterableExpkeyReqs<'a> {
3360    type Item = Result<ExpkeyReqs<'a>, ErrorContext>;
3361    fn next(&mut self) -> Option<Self::Item> {
3362        let mut pos;
3363        let mut r#type;
3364        loop {
3365            pos = self.pos;
3366            r#type = None;
3367            if self.buf.len() == self.pos {
3368                return None;
3369            }
3370            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
3371                self.pos = self.buf.len();
3372                break;
3373            };
3374            r#type = Some(header.r#type);
3375            let res = match header.r#type {
3376                1u16 => ExpkeyReqs::Requests({
3377                    let res = Some(IterableExpkey::with_loc(next, self.orig_loc));
3378                    let Some(val) = res else { break };
3379                    val
3380                }),
3381                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
3382                n => continue,
3383            };
3384            return Some(Ok(res));
3385        }
3386        Some(Err(ErrorContext::new(
3387            "ExpkeyReqs",
3388            r#type.and_then(|t| ExpkeyReqs::attr_from_type(t)),
3389            self.orig_loc,
3390            self.buf.as_ptr().wrapping_add(pos) as usize,
3391        )))
3392    }
3393}
3394impl<'a> std::fmt::Debug for IterableExpkeyReqs<'_> {
3395    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3396        let mut fmt = f.debug_struct("ExpkeyReqs");
3397        for attr in self.clone() {
3398            let attr = match attr {
3399                Ok(a) => a,
3400                Err(err) => {
3401                    fmt.finish()?;
3402                    f.write_str("Err(")?;
3403                    err.fmt(f)?;
3404                    return f.write_str(")");
3405                }
3406            };
3407            match attr {
3408                ExpkeyReqs::Requests(val) => fmt.field("Requests", &val),
3409            };
3410        }
3411        fmt.finish()
3412    }
3413}
3414impl IterableExpkeyReqs<'_> {
3415    pub fn lookup_attr(
3416        &self,
3417        offset: usize,
3418        missing_type: Option<u16>,
3419    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3420        let mut stack = Vec::new();
3421        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3422        if missing_type.is_some() && cur == offset {
3423            stack.push(("ExpkeyReqs", offset));
3424            return (
3425                stack,
3426                missing_type.and_then(|t| ExpkeyReqs::attr_from_type(t)),
3427            );
3428        }
3429        if cur > offset || cur + self.buf.len() < offset {
3430            return (stack, None);
3431        }
3432        let mut attrs = self.clone();
3433        let mut last_off = cur + attrs.pos;
3434        let mut missing = None;
3435        while let Some(attr) = attrs.next() {
3436            let Ok(attr) = attr else { break };
3437            match attr {
3438                ExpkeyReqs::Requests(val) => {
3439                    (stack, missing) = val.lookup_attr(offset, missing_type);
3440                    if !stack.is_empty() {
3441                        break;
3442                    }
3443                }
3444                _ => {}
3445            };
3446            last_off = cur + attrs.pos;
3447        }
3448        if !stack.is_empty() {
3449            stack.push(("ExpkeyReqs", cur));
3450        }
3451        (stack, missing)
3452    }
3453}
3454#[derive(Clone)]
3455pub enum CacheFlush {
3456    #[doc = "Associated type: [`CacheType`] (1 bit per enumeration)"]
3457    Mask(u32),
3458}
3459impl<'a> IterableCacheFlush<'a> {
3460    #[doc = "Associated type: [`CacheType`] (1 bit per enumeration)"]
3461    pub fn get_mask(&self) -> Result<u32, ErrorContext> {
3462        let mut iter = self.clone();
3463        iter.pos = 0;
3464        for attr in iter {
3465            if let Ok(CacheFlush::Mask(val)) = attr {
3466                return Ok(val);
3467            }
3468        }
3469        Err(ErrorContext::new_missing(
3470            "CacheFlush",
3471            "Mask",
3472            self.orig_loc,
3473            self.buf.as_ptr() as usize,
3474        ))
3475    }
3476}
3477impl CacheFlush {
3478    pub fn new<'a>(buf: &'a [u8]) -> IterableCacheFlush<'a> {
3479        IterableCacheFlush::with_loc(buf, buf.as_ptr() as usize)
3480    }
3481    fn attr_from_type(r#type: u16) -> Option<&'static str> {
3482        let res = match r#type {
3483            1u16 => "Mask",
3484            _ => return None,
3485        };
3486        Some(res)
3487    }
3488}
3489#[derive(Clone, Copy, Default)]
3490pub struct IterableCacheFlush<'a> {
3491    buf: &'a [u8],
3492    pos: usize,
3493    orig_loc: usize,
3494}
3495impl<'a> IterableCacheFlush<'a> {
3496    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3497        Self {
3498            buf,
3499            pos: 0,
3500            orig_loc,
3501        }
3502    }
3503    pub fn get_buf(&self) -> &'a [u8] {
3504        self.buf
3505    }
3506}
3507impl<'a> Iterator for IterableCacheFlush<'a> {
3508    type Item = Result<CacheFlush, ErrorContext>;
3509    fn next(&mut self) -> Option<Self::Item> {
3510        let mut pos;
3511        let mut r#type;
3512        loop {
3513            pos = self.pos;
3514            r#type = None;
3515            if self.buf.len() == self.pos {
3516                return None;
3517            }
3518            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
3519                self.pos = self.buf.len();
3520                break;
3521            };
3522            r#type = Some(header.r#type);
3523            let res = match header.r#type {
3524                1u16 => CacheFlush::Mask({
3525                    let res = parse_u32(next);
3526                    let Some(val) = res else { break };
3527                    val
3528                }),
3529                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
3530                n => continue,
3531            };
3532            return Some(Ok(res));
3533        }
3534        Some(Err(ErrorContext::new(
3535            "CacheFlush",
3536            r#type.and_then(|t| CacheFlush::attr_from_type(t)),
3537            self.orig_loc,
3538            self.buf.as_ptr().wrapping_add(pos) as usize,
3539        )))
3540    }
3541}
3542impl std::fmt::Debug for IterableCacheFlush<'_> {
3543    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3544        let mut fmt = f.debug_struct("CacheFlush");
3545        for attr in self.clone() {
3546            let attr = match attr {
3547                Ok(a) => a,
3548                Err(err) => {
3549                    fmt.finish()?;
3550                    f.write_str("Err(")?;
3551                    err.fmt(f)?;
3552                    return f.write_str(")");
3553                }
3554            };
3555            match attr {
3556                CacheFlush::Mask(val) => {
3557                    fmt.field("Mask", &FormatFlags(val.into(), CacheType::from_value))
3558                }
3559            };
3560        }
3561        fmt.finish()
3562    }
3563}
3564impl IterableCacheFlush<'_> {
3565    pub fn lookup_attr(
3566        &self,
3567        offset: usize,
3568        missing_type: Option<u16>,
3569    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3570        let mut stack = Vec::new();
3571        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3572        if missing_type.is_some() && cur == offset {
3573            stack.push(("CacheFlush", offset));
3574            return (
3575                stack,
3576                missing_type.and_then(|t| CacheFlush::attr_from_type(t)),
3577            );
3578        }
3579        if cur > offset || cur + self.buf.len() < offset {
3580            return (stack, None);
3581        }
3582        let mut attrs = self.clone();
3583        let mut last_off = cur + attrs.pos;
3584        while let Some(attr) = attrs.next() {
3585            let Ok(attr) = attr else { break };
3586            match attr {
3587                CacheFlush::Mask(val) => {
3588                    if last_off == offset {
3589                        stack.push(("Mask", last_off));
3590                        break;
3591                    }
3592                }
3593                _ => {}
3594            };
3595            last_off = cur + attrs.pos;
3596        }
3597        if !stack.is_empty() {
3598            stack.push(("CacheFlush", cur));
3599        }
3600        (stack, None)
3601    }
3602}
3603#[derive(Clone)]
3604pub enum UnlockIp<'a> {
3605    #[doc = "struct sockaddr_in or struct sockaddr_in6.\n"]
3606    Address(&'a [u8]),
3607}
3608impl<'a> IterableUnlockIp<'a> {
3609    #[doc = "struct sockaddr_in or struct sockaddr_in6.\n"]
3610    pub fn get_address(&self) -> Result<&'a [u8], ErrorContext> {
3611        let mut iter = self.clone();
3612        iter.pos = 0;
3613        for attr in iter {
3614            if let Ok(UnlockIp::Address(val)) = attr {
3615                return Ok(val);
3616            }
3617        }
3618        Err(ErrorContext::new_missing(
3619            "UnlockIp",
3620            "Address",
3621            self.orig_loc,
3622            self.buf.as_ptr() as usize,
3623        ))
3624    }
3625}
3626impl UnlockIp<'_> {
3627    pub fn new<'a>(buf: &'a [u8]) -> IterableUnlockIp<'a> {
3628        IterableUnlockIp::with_loc(buf, buf.as_ptr() as usize)
3629    }
3630    fn attr_from_type(r#type: u16) -> Option<&'static str> {
3631        let res = match r#type {
3632            1u16 => "Address",
3633            _ => return None,
3634        };
3635        Some(res)
3636    }
3637}
3638#[derive(Clone, Copy, Default)]
3639pub struct IterableUnlockIp<'a> {
3640    buf: &'a [u8],
3641    pos: usize,
3642    orig_loc: usize,
3643}
3644impl<'a> IterableUnlockIp<'a> {
3645    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3646        Self {
3647            buf,
3648            pos: 0,
3649            orig_loc,
3650        }
3651    }
3652    pub fn get_buf(&self) -> &'a [u8] {
3653        self.buf
3654    }
3655}
3656impl<'a> Iterator for IterableUnlockIp<'a> {
3657    type Item = Result<UnlockIp<'a>, ErrorContext>;
3658    fn next(&mut self) -> Option<Self::Item> {
3659        let mut pos;
3660        let mut r#type;
3661        loop {
3662            pos = self.pos;
3663            r#type = None;
3664            if self.buf.len() == self.pos {
3665                return None;
3666            }
3667            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
3668                self.pos = self.buf.len();
3669                break;
3670            };
3671            r#type = Some(header.r#type);
3672            let res = match header.r#type {
3673                1u16 => UnlockIp::Address({
3674                    let res = Some(next);
3675                    let Some(val) = res else { break };
3676                    val
3677                }),
3678                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
3679                n => continue,
3680            };
3681            return Some(Ok(res));
3682        }
3683        Some(Err(ErrorContext::new(
3684            "UnlockIp",
3685            r#type.and_then(|t| UnlockIp::attr_from_type(t)),
3686            self.orig_loc,
3687            self.buf.as_ptr().wrapping_add(pos) as usize,
3688        )))
3689    }
3690}
3691impl<'a> std::fmt::Debug for IterableUnlockIp<'_> {
3692    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3693        let mut fmt = f.debug_struct("UnlockIp");
3694        for attr in self.clone() {
3695            let attr = match attr {
3696                Ok(a) => a,
3697                Err(err) => {
3698                    fmt.finish()?;
3699                    f.write_str("Err(")?;
3700                    err.fmt(f)?;
3701                    return f.write_str(")");
3702                }
3703            };
3704            match attr {
3705                UnlockIp::Address(val) => fmt.field("Address", &val),
3706            };
3707        }
3708        fmt.finish()
3709    }
3710}
3711impl IterableUnlockIp<'_> {
3712    pub fn lookup_attr(
3713        &self,
3714        offset: usize,
3715        missing_type: Option<u16>,
3716    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3717        let mut stack = Vec::new();
3718        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3719        if missing_type.is_some() && cur == offset {
3720            stack.push(("UnlockIp", offset));
3721            return (
3722                stack,
3723                missing_type.and_then(|t| UnlockIp::attr_from_type(t)),
3724            );
3725        }
3726        if cur > offset || cur + self.buf.len() < offset {
3727            return (stack, None);
3728        }
3729        let mut attrs = self.clone();
3730        let mut last_off = cur + attrs.pos;
3731        while let Some(attr) = attrs.next() {
3732            let Ok(attr) = attr else { break };
3733            match attr {
3734                UnlockIp::Address(val) => {
3735                    if last_off == offset {
3736                        stack.push(("Address", last_off));
3737                        break;
3738                    }
3739                }
3740                _ => {}
3741            };
3742            last_off = cur + attrs.pos;
3743        }
3744        if !stack.is_empty() {
3745            stack.push(("UnlockIp", cur));
3746        }
3747        (stack, None)
3748    }
3749}
3750#[derive(Clone)]
3751pub enum UnlockFilesystem<'a> {
3752    #[doc = "Filesystem path whose state should be released.\n"]
3753    Path(&'a CStr),
3754}
3755impl<'a> IterableUnlockFilesystem<'a> {
3756    #[doc = "Filesystem path whose state should be released.\n"]
3757    pub fn get_path(&self) -> Result<&'a CStr, ErrorContext> {
3758        let mut iter = self.clone();
3759        iter.pos = 0;
3760        for attr in iter {
3761            if let Ok(UnlockFilesystem::Path(val)) = attr {
3762                return Ok(val);
3763            }
3764        }
3765        Err(ErrorContext::new_missing(
3766            "UnlockFilesystem",
3767            "Path",
3768            self.orig_loc,
3769            self.buf.as_ptr() as usize,
3770        ))
3771    }
3772}
3773impl UnlockFilesystem<'_> {
3774    pub fn new<'a>(buf: &'a [u8]) -> IterableUnlockFilesystem<'a> {
3775        IterableUnlockFilesystem::with_loc(buf, buf.as_ptr() as usize)
3776    }
3777    fn attr_from_type(r#type: u16) -> Option<&'static str> {
3778        let res = match r#type {
3779            1u16 => "Path",
3780            _ => return None,
3781        };
3782        Some(res)
3783    }
3784}
3785#[derive(Clone, Copy, Default)]
3786pub struct IterableUnlockFilesystem<'a> {
3787    buf: &'a [u8],
3788    pos: usize,
3789    orig_loc: usize,
3790}
3791impl<'a> IterableUnlockFilesystem<'a> {
3792    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3793        Self {
3794            buf,
3795            pos: 0,
3796            orig_loc,
3797        }
3798    }
3799    pub fn get_buf(&self) -> &'a [u8] {
3800        self.buf
3801    }
3802}
3803impl<'a> Iterator for IterableUnlockFilesystem<'a> {
3804    type Item = Result<UnlockFilesystem<'a>, ErrorContext>;
3805    fn next(&mut self) -> Option<Self::Item> {
3806        let mut pos;
3807        let mut r#type;
3808        loop {
3809            pos = self.pos;
3810            r#type = None;
3811            if self.buf.len() == self.pos {
3812                return None;
3813            }
3814            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
3815                self.pos = self.buf.len();
3816                break;
3817            };
3818            r#type = Some(header.r#type);
3819            let res = match header.r#type {
3820                1u16 => UnlockFilesystem::Path({
3821                    let res = CStr::from_bytes_with_nul(next).ok();
3822                    let Some(val) = res else { break };
3823                    val
3824                }),
3825                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
3826                n => continue,
3827            };
3828            return Some(Ok(res));
3829        }
3830        Some(Err(ErrorContext::new(
3831            "UnlockFilesystem",
3832            r#type.and_then(|t| UnlockFilesystem::attr_from_type(t)),
3833            self.orig_loc,
3834            self.buf.as_ptr().wrapping_add(pos) as usize,
3835        )))
3836    }
3837}
3838impl<'a> std::fmt::Debug for IterableUnlockFilesystem<'_> {
3839    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3840        let mut fmt = f.debug_struct("UnlockFilesystem");
3841        for attr in self.clone() {
3842            let attr = match attr {
3843                Ok(a) => a,
3844                Err(err) => {
3845                    fmt.finish()?;
3846                    f.write_str("Err(")?;
3847                    err.fmt(f)?;
3848                    return f.write_str(")");
3849                }
3850            };
3851            match attr {
3852                UnlockFilesystem::Path(val) => fmt.field("Path", &val),
3853            };
3854        }
3855        fmt.finish()
3856    }
3857}
3858impl IterableUnlockFilesystem<'_> {
3859    pub fn lookup_attr(
3860        &self,
3861        offset: usize,
3862        missing_type: Option<u16>,
3863    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3864        let mut stack = Vec::new();
3865        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3866        if missing_type.is_some() && cur == offset {
3867            stack.push(("UnlockFilesystem", offset));
3868            return (
3869                stack,
3870                missing_type.and_then(|t| UnlockFilesystem::attr_from_type(t)),
3871            );
3872        }
3873        if cur > offset || cur + self.buf.len() < offset {
3874            return (stack, None);
3875        }
3876        let mut attrs = self.clone();
3877        let mut last_off = cur + attrs.pos;
3878        while let Some(attr) = attrs.next() {
3879            let Ok(attr) = attr else { break };
3880            match attr {
3881                UnlockFilesystem::Path(val) => {
3882                    if last_off == offset {
3883                        stack.push(("Path", last_off));
3884                        break;
3885                    }
3886                }
3887                _ => {}
3888            };
3889            last_off = cur + attrs.pos;
3890        }
3891        if !stack.is_empty() {
3892            stack.push(("UnlockFilesystem", cur));
3893        }
3894        (stack, None)
3895    }
3896}
3897#[derive(Clone)]
3898pub enum UnlockExport<'a> {
3899    #[doc = "Export path whose NFSv4 state should be revoked. All state (opens,\nlocks, delegations, layouts) acquired through any export of this path is\nrevoked, regardless of which client holds the state. Intended for use\nafter all clients have been unexported from a given path, enabling the\nunderlying filesystem to be unmounted.\n"]
3900    Path(&'a CStr),
3901}
3902impl<'a> IterableUnlockExport<'a> {
3903    #[doc = "Export path whose NFSv4 state should be revoked. All state (opens,\nlocks, delegations, layouts) acquired through any export of this path is\nrevoked, regardless of which client holds the state. Intended for use\nafter all clients have been unexported from a given path, enabling the\nunderlying filesystem to be unmounted.\n"]
3904    pub fn get_path(&self) -> Result<&'a CStr, ErrorContext> {
3905        let mut iter = self.clone();
3906        iter.pos = 0;
3907        for attr in iter {
3908            if let Ok(UnlockExport::Path(val)) = attr {
3909                return Ok(val);
3910            }
3911        }
3912        Err(ErrorContext::new_missing(
3913            "UnlockExport",
3914            "Path",
3915            self.orig_loc,
3916            self.buf.as_ptr() as usize,
3917        ))
3918    }
3919}
3920impl UnlockExport<'_> {
3921    pub fn new<'a>(buf: &'a [u8]) -> IterableUnlockExport<'a> {
3922        IterableUnlockExport::with_loc(buf, buf.as_ptr() as usize)
3923    }
3924    fn attr_from_type(r#type: u16) -> Option<&'static str> {
3925        let res = match r#type {
3926            1u16 => "Path",
3927            _ => return None,
3928        };
3929        Some(res)
3930    }
3931}
3932#[derive(Clone, Copy, Default)]
3933pub struct IterableUnlockExport<'a> {
3934    buf: &'a [u8],
3935    pos: usize,
3936    orig_loc: usize,
3937}
3938impl<'a> IterableUnlockExport<'a> {
3939    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3940        Self {
3941            buf,
3942            pos: 0,
3943            orig_loc,
3944        }
3945    }
3946    pub fn get_buf(&self) -> &'a [u8] {
3947        self.buf
3948    }
3949}
3950impl<'a> Iterator for IterableUnlockExport<'a> {
3951    type Item = Result<UnlockExport<'a>, ErrorContext>;
3952    fn next(&mut self) -> Option<Self::Item> {
3953        let mut pos;
3954        let mut r#type;
3955        loop {
3956            pos = self.pos;
3957            r#type = None;
3958            if self.buf.len() == self.pos {
3959                return None;
3960            }
3961            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
3962                self.pos = self.buf.len();
3963                break;
3964            };
3965            r#type = Some(header.r#type);
3966            let res = match header.r#type {
3967                1u16 => UnlockExport::Path({
3968                    let res = CStr::from_bytes_with_nul(next).ok();
3969                    let Some(val) = res else { break };
3970                    val
3971                }),
3972                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
3973                n => continue,
3974            };
3975            return Some(Ok(res));
3976        }
3977        Some(Err(ErrorContext::new(
3978            "UnlockExport",
3979            r#type.and_then(|t| UnlockExport::attr_from_type(t)),
3980            self.orig_loc,
3981            self.buf.as_ptr().wrapping_add(pos) as usize,
3982        )))
3983    }
3984}
3985impl<'a> std::fmt::Debug for IterableUnlockExport<'_> {
3986    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3987        let mut fmt = f.debug_struct("UnlockExport");
3988        for attr in self.clone() {
3989            let attr = match attr {
3990                Ok(a) => a,
3991                Err(err) => {
3992                    fmt.finish()?;
3993                    f.write_str("Err(")?;
3994                    err.fmt(f)?;
3995                    return f.write_str(")");
3996                }
3997            };
3998            match attr {
3999                UnlockExport::Path(val) => fmt.field("Path", &val),
4000            };
4001        }
4002        fmt.finish()
4003    }
4004}
4005impl IterableUnlockExport<'_> {
4006    pub fn lookup_attr(
4007        &self,
4008        offset: usize,
4009        missing_type: Option<u16>,
4010    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
4011        let mut stack = Vec::new();
4012        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
4013        if missing_type.is_some() && cur == offset {
4014            stack.push(("UnlockExport", offset));
4015            return (
4016                stack,
4017                missing_type.and_then(|t| UnlockExport::attr_from_type(t)),
4018            );
4019        }
4020        if cur > offset || cur + self.buf.len() < offset {
4021            return (stack, None);
4022        }
4023        let mut attrs = self.clone();
4024        let mut last_off = cur + attrs.pos;
4025        while let Some(attr) = attrs.next() {
4026            let Ok(attr) = attr else { break };
4027            match attr {
4028                UnlockExport::Path(val) => {
4029                    if last_off == offset {
4030                        stack.push(("Path", last_off));
4031                        break;
4032                    }
4033                }
4034                _ => {}
4035            };
4036            last_off = cur + attrs.pos;
4037        }
4038        if !stack.is_empty() {
4039            stack.push(("UnlockExport", cur));
4040        }
4041        (stack, None)
4042    }
4043}
4044pub struct PushCacheNotify<Prev: Pusher> {
4045    pub(crate) prev: Option<Prev>,
4046    pub(crate) header_offset: Option<usize>,
4047}
4048impl<Prev: Pusher> Pusher for PushCacheNotify<Prev> {
4049    fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4050        self.prev.as_mut().unwrap().as_vec_mut()
4051    }
4052    fn as_vec(&self) -> &Vec<u8> {
4053        self.prev.as_ref().unwrap().as_vec()
4054    }
4055}
4056impl<Prev: Pusher> PushCacheNotify<Prev> {
4057    pub fn new(prev: Prev) -> Self {
4058        Self {
4059            prev: Some(prev),
4060            header_offset: None,
4061        }
4062    }
4063    pub fn end_nested(mut self) -> Prev {
4064        let mut prev = self.prev.take().unwrap();
4065        if let Some(header_offset) = &self.header_offset {
4066            finalize_nested_header(prev.as_vec_mut(), *header_offset);
4067        }
4068        prev
4069    }
4070    #[doc = "Associated type: [`CacheType`] (enum)"]
4071    pub fn push_cache_type(mut self, value: u32) -> Self {
4072        push_header(self.as_vec_mut(), 1u16, 4 as u16);
4073        self.as_vec_mut().extend(value.to_ne_bytes());
4074        self
4075    }
4076}
4077impl<Prev: Pusher> Drop for PushCacheNotify<Prev> {
4078    fn drop(&mut self) {
4079        if let Some(prev) = &mut self.prev {
4080            if let Some(header_offset) = &self.header_offset {
4081                finalize_nested_header(prev.as_vec_mut(), *header_offset);
4082            }
4083        }
4084    }
4085}
4086pub struct PushRpcStatus<Prev: Pusher> {
4087    pub(crate) prev: Option<Prev>,
4088    pub(crate) header_offset: Option<usize>,
4089}
4090impl<Prev: Pusher> Pusher for PushRpcStatus<Prev> {
4091    fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4092        self.prev.as_mut().unwrap().as_vec_mut()
4093    }
4094    fn as_vec(&self) -> &Vec<u8> {
4095        self.prev.as_ref().unwrap().as_vec()
4096    }
4097}
4098impl<Prev: Pusher> PushRpcStatus<Prev> {
4099    pub fn new(prev: Prev) -> Self {
4100        Self {
4101            prev: Some(prev),
4102            header_offset: None,
4103        }
4104    }
4105    pub fn end_nested(mut self) -> Prev {
4106        let mut prev = self.prev.take().unwrap();
4107        if let Some(header_offset) = &self.header_offset {
4108            finalize_nested_header(prev.as_vec_mut(), *header_offset);
4109        }
4110        prev
4111    }
4112    pub fn push_xid(mut self, value: u32) -> Self {
4113        push_header(self.as_vec_mut(), 1u16, 4 as u16);
4114        self.as_vec_mut().extend(value.to_be_bytes());
4115        self
4116    }
4117    pub fn push_flags(mut self, value: u32) -> Self {
4118        push_header(self.as_vec_mut(), 2u16, 4 as u16);
4119        self.as_vec_mut().extend(value.to_ne_bytes());
4120        self
4121    }
4122    pub fn push_prog(mut self, value: u32) -> Self {
4123        push_header(self.as_vec_mut(), 3u16, 4 as u16);
4124        self.as_vec_mut().extend(value.to_ne_bytes());
4125        self
4126    }
4127    pub fn push_version(mut self, value: u8) -> Self {
4128        push_header(self.as_vec_mut(), 4u16, 1 as u16);
4129        self.as_vec_mut().extend(value.to_ne_bytes());
4130        self
4131    }
4132    pub fn push_proc(mut self, value: u32) -> Self {
4133        push_header(self.as_vec_mut(), 5u16, 4 as u16);
4134        self.as_vec_mut().extend(value.to_ne_bytes());
4135        self
4136    }
4137    pub fn push_service_time(mut self, value: i64) -> Self {
4138        push_header(self.as_vec_mut(), 6u16, 8 as u16);
4139        self.as_vec_mut().extend(value.to_ne_bytes());
4140        self
4141    }
4142    pub fn push_pad(mut self, value: &[u8]) -> Self {
4143        push_header(self.as_vec_mut(), 7u16, value.len() as u16);
4144        self.as_vec_mut().extend(value);
4145        self
4146    }
4147    pub fn push_saddr4(mut self, value: std::net::Ipv4Addr) -> Self {
4148        push_header(self.as_vec_mut(), 8u16, 4 as u16);
4149        self.as_vec_mut().extend(&value.to_bits().to_be_bytes());
4150        self
4151    }
4152    pub fn push_daddr4(mut self, value: std::net::Ipv4Addr) -> Self {
4153        push_header(self.as_vec_mut(), 9u16, 4 as u16);
4154        self.as_vec_mut().extend(&value.to_bits().to_be_bytes());
4155        self
4156    }
4157    pub fn push_saddr6(mut self, value: &[u8]) -> Self {
4158        push_header(self.as_vec_mut(), 10u16, value.len() as u16);
4159        self.as_vec_mut().extend(value);
4160        self
4161    }
4162    pub fn push_daddr6(mut self, value: &[u8]) -> Self {
4163        push_header(self.as_vec_mut(), 11u16, value.len() as u16);
4164        self.as_vec_mut().extend(value);
4165        self
4166    }
4167    pub fn push_sport(mut self, value: u16) -> Self {
4168        push_header(self.as_vec_mut(), 12u16, 2 as u16);
4169        self.as_vec_mut().extend(value.to_be_bytes());
4170        self
4171    }
4172    pub fn push_dport(mut self, value: u16) -> Self {
4173        push_header(self.as_vec_mut(), 13u16, 2 as u16);
4174        self.as_vec_mut().extend(value.to_be_bytes());
4175        self
4176    }
4177    #[doc = "Attribute may repeat multiple times (treat it as array)"]
4178    pub fn push_compound_ops(mut self, value: u32) -> Self {
4179        push_header(self.as_vec_mut(), 14u16, 4 as u16);
4180        self.as_vec_mut().extend(value.to_ne_bytes());
4181        self
4182    }
4183}
4184impl<Prev: Pusher> Drop for PushRpcStatus<Prev> {
4185    fn drop(&mut self) {
4186        if let Some(prev) = &mut self.prev {
4187            if let Some(header_offset) = &self.header_offset {
4188                finalize_nested_header(prev.as_vec_mut(), *header_offset);
4189            }
4190        }
4191    }
4192}
4193pub struct PushServer<Prev: Pusher> {
4194    pub(crate) prev: Option<Prev>,
4195    pub(crate) header_offset: Option<usize>,
4196}
4197impl<Prev: Pusher> Pusher for PushServer<Prev> {
4198    fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4199        self.prev.as_mut().unwrap().as_vec_mut()
4200    }
4201    fn as_vec(&self) -> &Vec<u8> {
4202        self.prev.as_ref().unwrap().as_vec()
4203    }
4204}
4205impl<Prev: Pusher> PushServer<Prev> {
4206    pub fn new(prev: Prev) -> Self {
4207        Self {
4208            prev: Some(prev),
4209            header_offset: None,
4210        }
4211    }
4212    pub fn end_nested(mut self) -> Prev {
4213        let mut prev = self.prev.take().unwrap();
4214        if let Some(header_offset) = &self.header_offset {
4215            finalize_nested_header(prev.as_vec_mut(), *header_offset);
4216        }
4217        prev
4218    }
4219    #[doc = "Attribute may repeat multiple times (treat it as array)"]
4220    pub fn push_threads(mut self, value: u32) -> Self {
4221        push_header(self.as_vec_mut(), 1u16, 4 as u16);
4222        self.as_vec_mut().extend(value.to_ne_bytes());
4223        self
4224    }
4225    pub fn push_gracetime(mut self, value: u32) -> Self {
4226        push_header(self.as_vec_mut(), 2u16, 4 as u16);
4227        self.as_vec_mut().extend(value.to_ne_bytes());
4228        self
4229    }
4230    pub fn push_leasetime(mut self, value: u32) -> Self {
4231        push_header(self.as_vec_mut(), 3u16, 4 as u16);
4232        self.as_vec_mut().extend(value.to_ne_bytes());
4233        self
4234    }
4235    pub fn push_scope(mut self, value: &CStr) -> Self {
4236        push_header(
4237            self.as_vec_mut(),
4238            4u16,
4239            value.to_bytes_with_nul().len() as u16,
4240        );
4241        self.as_vec_mut().extend(value.to_bytes_with_nul());
4242        self
4243    }
4244    pub fn push_scope_bytes(mut self, value: &[u8]) -> Self {
4245        push_header(self.as_vec_mut(), 4u16, (value.len() + 1) as u16);
4246        self.as_vec_mut().extend(value);
4247        self.as_vec_mut().push(0);
4248        self
4249    }
4250    pub fn push_min_threads(mut self, value: u32) -> Self {
4251        push_header(self.as_vec_mut(), 5u16, 4 as u16);
4252        self.as_vec_mut().extend(value.to_ne_bytes());
4253        self
4254    }
4255    pub fn push_fh_key(mut self, value: &[u8]) -> Self {
4256        push_header(self.as_vec_mut(), 6u16, value.len() as u16);
4257        self.as_vec_mut().extend(value);
4258        self
4259    }
4260}
4261impl<Prev: Pusher> Drop for PushServer<Prev> {
4262    fn drop(&mut self) {
4263        if let Some(prev) = &mut self.prev {
4264            if let Some(header_offset) = &self.header_offset {
4265                finalize_nested_header(prev.as_vec_mut(), *header_offset);
4266            }
4267        }
4268    }
4269}
4270pub struct PushVersion<Prev: Pusher> {
4271    pub(crate) prev: Option<Prev>,
4272    pub(crate) header_offset: Option<usize>,
4273}
4274impl<Prev: Pusher> Pusher for PushVersion<Prev> {
4275    fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4276        self.prev.as_mut().unwrap().as_vec_mut()
4277    }
4278    fn as_vec(&self) -> &Vec<u8> {
4279        self.prev.as_ref().unwrap().as_vec()
4280    }
4281}
4282impl<Prev: Pusher> PushVersion<Prev> {
4283    pub fn new(prev: Prev) -> Self {
4284        Self {
4285            prev: Some(prev),
4286            header_offset: None,
4287        }
4288    }
4289    pub fn end_nested(mut self) -> Prev {
4290        let mut prev = self.prev.take().unwrap();
4291        if let Some(header_offset) = &self.header_offset {
4292            finalize_nested_header(prev.as_vec_mut(), *header_offset);
4293        }
4294        prev
4295    }
4296    pub fn push_major(mut self, value: u32) -> Self {
4297        push_header(self.as_vec_mut(), 1u16, 4 as u16);
4298        self.as_vec_mut().extend(value.to_ne_bytes());
4299        self
4300    }
4301    pub fn push_minor(mut self, value: u32) -> Self {
4302        push_header(self.as_vec_mut(), 2u16, 4 as u16);
4303        self.as_vec_mut().extend(value.to_ne_bytes());
4304        self
4305    }
4306    pub fn push_enabled(mut self, value: ()) -> Self {
4307        push_header(self.as_vec_mut(), 3u16, 0 as u16);
4308        self
4309    }
4310}
4311impl<Prev: Pusher> Drop for PushVersion<Prev> {
4312    fn drop(&mut self) {
4313        if let Some(prev) = &mut self.prev {
4314            if let Some(header_offset) = &self.header_offset {
4315                finalize_nested_header(prev.as_vec_mut(), *header_offset);
4316            }
4317        }
4318    }
4319}
4320pub struct PushServerProto<Prev: Pusher> {
4321    pub(crate) prev: Option<Prev>,
4322    pub(crate) header_offset: Option<usize>,
4323}
4324impl<Prev: Pusher> Pusher for PushServerProto<Prev> {
4325    fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4326        self.prev.as_mut().unwrap().as_vec_mut()
4327    }
4328    fn as_vec(&self) -> &Vec<u8> {
4329        self.prev.as_ref().unwrap().as_vec()
4330    }
4331}
4332impl<Prev: Pusher> PushServerProto<Prev> {
4333    pub fn new(prev: Prev) -> Self {
4334        Self {
4335            prev: Some(prev),
4336            header_offset: None,
4337        }
4338    }
4339    pub fn end_nested(mut self) -> Prev {
4340        let mut prev = self.prev.take().unwrap();
4341        if let Some(header_offset) = &self.header_offset {
4342            finalize_nested_header(prev.as_vec_mut(), *header_offset);
4343        }
4344        prev
4345    }
4346    #[doc = "Attribute may repeat multiple times (treat it as array)"]
4347    pub fn nested_version(mut self) -> PushVersion<Self> {
4348        let header_offset = push_nested_header(self.as_vec_mut(), 1u16);
4349        PushVersion {
4350            prev: Some(self),
4351            header_offset: Some(header_offset),
4352        }
4353    }
4354}
4355impl<Prev: Pusher> Drop for PushServerProto<Prev> {
4356    fn drop(&mut self) {
4357        if let Some(prev) = &mut self.prev {
4358            if let Some(header_offset) = &self.header_offset {
4359                finalize_nested_header(prev.as_vec_mut(), *header_offset);
4360            }
4361        }
4362    }
4363}
4364pub struct PushSock<Prev: Pusher> {
4365    pub(crate) prev: Option<Prev>,
4366    pub(crate) header_offset: Option<usize>,
4367}
4368impl<Prev: Pusher> Pusher for PushSock<Prev> {
4369    fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4370        self.prev.as_mut().unwrap().as_vec_mut()
4371    }
4372    fn as_vec(&self) -> &Vec<u8> {
4373        self.prev.as_ref().unwrap().as_vec()
4374    }
4375}
4376impl<Prev: Pusher> PushSock<Prev> {
4377    pub fn new(prev: Prev) -> Self {
4378        Self {
4379            prev: Some(prev),
4380            header_offset: None,
4381        }
4382    }
4383    pub fn end_nested(mut self) -> Prev {
4384        let mut prev = self.prev.take().unwrap();
4385        if let Some(header_offset) = &self.header_offset {
4386            finalize_nested_header(prev.as_vec_mut(), *header_offset);
4387        }
4388        prev
4389    }
4390    pub fn push_addr(mut self, value: &[u8]) -> Self {
4391        push_header(self.as_vec_mut(), 1u16, value.len() as u16);
4392        self.as_vec_mut().extend(value);
4393        self
4394    }
4395    pub fn push_transport_name(mut self, value: &CStr) -> Self {
4396        push_header(
4397            self.as_vec_mut(),
4398            2u16,
4399            value.to_bytes_with_nul().len() as u16,
4400        );
4401        self.as_vec_mut().extend(value.to_bytes_with_nul());
4402        self
4403    }
4404    pub fn push_transport_name_bytes(mut self, value: &[u8]) -> Self {
4405        push_header(self.as_vec_mut(), 2u16, (value.len() + 1) as u16);
4406        self.as_vec_mut().extend(value);
4407        self.as_vec_mut().push(0);
4408        self
4409    }
4410}
4411impl<Prev: Pusher> Drop for PushSock<Prev> {
4412    fn drop(&mut self) {
4413        if let Some(prev) = &mut self.prev {
4414            if let Some(header_offset) = &self.header_offset {
4415                finalize_nested_header(prev.as_vec_mut(), *header_offset);
4416            }
4417        }
4418    }
4419}
4420pub struct PushServerSock<Prev: Pusher> {
4421    pub(crate) prev: Option<Prev>,
4422    pub(crate) header_offset: Option<usize>,
4423}
4424impl<Prev: Pusher> Pusher for PushServerSock<Prev> {
4425    fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4426        self.prev.as_mut().unwrap().as_vec_mut()
4427    }
4428    fn as_vec(&self) -> &Vec<u8> {
4429        self.prev.as_ref().unwrap().as_vec()
4430    }
4431}
4432impl<Prev: Pusher> PushServerSock<Prev> {
4433    pub fn new(prev: Prev) -> Self {
4434        Self {
4435            prev: Some(prev),
4436            header_offset: None,
4437        }
4438    }
4439    pub fn end_nested(mut self) -> Prev {
4440        let mut prev = self.prev.take().unwrap();
4441        if let Some(header_offset) = &self.header_offset {
4442            finalize_nested_header(prev.as_vec_mut(), *header_offset);
4443        }
4444        prev
4445    }
4446    #[doc = "Attribute may repeat multiple times (treat it as array)"]
4447    pub fn nested_addr(mut self) -> PushSock<Self> {
4448        let header_offset = push_nested_header(self.as_vec_mut(), 1u16);
4449        PushSock {
4450            prev: Some(self),
4451            header_offset: Some(header_offset),
4452        }
4453    }
4454}
4455impl<Prev: Pusher> Drop for PushServerSock<Prev> {
4456    fn drop(&mut self) {
4457        if let Some(prev) = &mut self.prev {
4458            if let Some(header_offset) = &self.header_offset {
4459                finalize_nested_header(prev.as_vec_mut(), *header_offset);
4460            }
4461        }
4462    }
4463}
4464pub struct PushPoolMode<Prev: Pusher> {
4465    pub(crate) prev: Option<Prev>,
4466    pub(crate) header_offset: Option<usize>,
4467}
4468impl<Prev: Pusher> Pusher for PushPoolMode<Prev> {
4469    fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4470        self.prev.as_mut().unwrap().as_vec_mut()
4471    }
4472    fn as_vec(&self) -> &Vec<u8> {
4473        self.prev.as_ref().unwrap().as_vec()
4474    }
4475}
4476impl<Prev: Pusher> PushPoolMode<Prev> {
4477    pub fn new(prev: Prev) -> Self {
4478        Self {
4479            prev: Some(prev),
4480            header_offset: None,
4481        }
4482    }
4483    pub fn end_nested(mut self) -> Prev {
4484        let mut prev = self.prev.take().unwrap();
4485        if let Some(header_offset) = &self.header_offset {
4486            finalize_nested_header(prev.as_vec_mut(), *header_offset);
4487        }
4488        prev
4489    }
4490    pub fn push_mode(mut self, value: &CStr) -> Self {
4491        push_header(
4492            self.as_vec_mut(),
4493            1u16,
4494            value.to_bytes_with_nul().len() as u16,
4495        );
4496        self.as_vec_mut().extend(value.to_bytes_with_nul());
4497        self
4498    }
4499    pub fn push_mode_bytes(mut self, value: &[u8]) -> Self {
4500        push_header(self.as_vec_mut(), 1u16, (value.len() + 1) as u16);
4501        self.as_vec_mut().extend(value);
4502        self.as_vec_mut().push(0);
4503        self
4504    }
4505    pub fn push_npools(mut self, value: u32) -> Self {
4506        push_header(self.as_vec_mut(), 2u16, 4 as u16);
4507        self.as_vec_mut().extend(value.to_ne_bytes());
4508        self
4509    }
4510}
4511impl<Prev: Pusher> Drop for PushPoolMode<Prev> {
4512    fn drop(&mut self) {
4513        if let Some(prev) = &mut self.prev {
4514            if let Some(header_offset) = &self.header_offset {
4515                finalize_nested_header(prev.as_vec_mut(), *header_offset);
4516            }
4517        }
4518    }
4519}
4520pub struct PushFslocation<Prev: Pusher> {
4521    pub(crate) prev: Option<Prev>,
4522    pub(crate) header_offset: Option<usize>,
4523}
4524impl<Prev: Pusher> Pusher for PushFslocation<Prev> {
4525    fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4526        self.prev.as_mut().unwrap().as_vec_mut()
4527    }
4528    fn as_vec(&self) -> &Vec<u8> {
4529        self.prev.as_ref().unwrap().as_vec()
4530    }
4531}
4532impl<Prev: Pusher> PushFslocation<Prev> {
4533    pub fn new(prev: Prev) -> Self {
4534        Self {
4535            prev: Some(prev),
4536            header_offset: None,
4537        }
4538    }
4539    pub fn end_nested(mut self) -> Prev {
4540        let mut prev = self.prev.take().unwrap();
4541        if let Some(header_offset) = &self.header_offset {
4542            finalize_nested_header(prev.as_vec_mut(), *header_offset);
4543        }
4544        prev
4545    }
4546    pub fn push_host(mut self, value: &CStr) -> Self {
4547        push_header(
4548            self.as_vec_mut(),
4549            1u16,
4550            value.to_bytes_with_nul().len() as u16,
4551        );
4552        self.as_vec_mut().extend(value.to_bytes_with_nul());
4553        self
4554    }
4555    pub fn push_host_bytes(mut self, value: &[u8]) -> Self {
4556        push_header(self.as_vec_mut(), 1u16, (value.len() + 1) as u16);
4557        self.as_vec_mut().extend(value);
4558        self.as_vec_mut().push(0);
4559        self
4560    }
4561    pub fn push_path(mut self, value: &CStr) -> Self {
4562        push_header(
4563            self.as_vec_mut(),
4564            2u16,
4565            value.to_bytes_with_nul().len() as u16,
4566        );
4567        self.as_vec_mut().extend(value.to_bytes_with_nul());
4568        self
4569    }
4570    pub fn push_path_bytes(mut self, value: &[u8]) -> Self {
4571        push_header(self.as_vec_mut(), 2u16, (value.len() + 1) as u16);
4572        self.as_vec_mut().extend(value);
4573        self.as_vec_mut().push(0);
4574        self
4575    }
4576}
4577impl<Prev: Pusher> Drop for PushFslocation<Prev> {
4578    fn drop(&mut self) {
4579        if let Some(prev) = &mut self.prev {
4580            if let Some(header_offset) = &self.header_offset {
4581                finalize_nested_header(prev.as_vec_mut(), *header_offset);
4582            }
4583        }
4584    }
4585}
4586pub struct PushFslocations<Prev: Pusher> {
4587    pub(crate) prev: Option<Prev>,
4588    pub(crate) header_offset: Option<usize>,
4589}
4590impl<Prev: Pusher> Pusher for PushFslocations<Prev> {
4591    fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4592        self.prev.as_mut().unwrap().as_vec_mut()
4593    }
4594    fn as_vec(&self) -> &Vec<u8> {
4595        self.prev.as_ref().unwrap().as_vec()
4596    }
4597}
4598impl<Prev: Pusher> PushFslocations<Prev> {
4599    pub fn new(prev: Prev) -> Self {
4600        Self {
4601            prev: Some(prev),
4602            header_offset: None,
4603        }
4604    }
4605    pub fn end_nested(mut self) -> Prev {
4606        let mut prev = self.prev.take().unwrap();
4607        if let Some(header_offset) = &self.header_offset {
4608            finalize_nested_header(prev.as_vec_mut(), *header_offset);
4609        }
4610        prev
4611    }
4612    #[doc = "Attribute may repeat multiple times (treat it as array)"]
4613    pub fn nested_location(mut self) -> PushFslocation<Self> {
4614        let header_offset = push_nested_header(self.as_vec_mut(), 1u16);
4615        PushFslocation {
4616            prev: Some(self),
4617            header_offset: Some(header_offset),
4618        }
4619    }
4620}
4621impl<Prev: Pusher> Drop for PushFslocations<Prev> {
4622    fn drop(&mut self) {
4623        if let Some(prev) = &mut self.prev {
4624            if let Some(header_offset) = &self.header_offset {
4625                finalize_nested_header(prev.as_vec_mut(), *header_offset);
4626            }
4627        }
4628    }
4629}
4630pub struct PushAuthFlavor<Prev: Pusher> {
4631    pub(crate) prev: Option<Prev>,
4632    pub(crate) header_offset: Option<usize>,
4633}
4634impl<Prev: Pusher> Pusher for PushAuthFlavor<Prev> {
4635    fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4636        self.prev.as_mut().unwrap().as_vec_mut()
4637    }
4638    fn as_vec(&self) -> &Vec<u8> {
4639        self.prev.as_ref().unwrap().as_vec()
4640    }
4641}
4642impl<Prev: Pusher> PushAuthFlavor<Prev> {
4643    pub fn new(prev: Prev) -> Self {
4644        Self {
4645            prev: Some(prev),
4646            header_offset: None,
4647        }
4648    }
4649    pub fn end_nested(mut self) -> Prev {
4650        let mut prev = self.prev.take().unwrap();
4651        if let Some(header_offset) = &self.header_offset {
4652            finalize_nested_header(prev.as_vec_mut(), *header_offset);
4653        }
4654        prev
4655    }
4656    pub fn push_pseudoflavor(mut self, value: u32) -> Self {
4657        push_header(self.as_vec_mut(), 1u16, 4 as u16);
4658        self.as_vec_mut().extend(value.to_ne_bytes());
4659        self
4660    }
4661    #[doc = "Associated type: [`ExportFlags`] (1 bit per enumeration)"]
4662    pub fn push_flags(mut self, value: u32) -> Self {
4663        push_header(self.as_vec_mut(), 2u16, 4 as u16);
4664        self.as_vec_mut().extend(value.to_ne_bytes());
4665        self
4666    }
4667}
4668impl<Prev: Pusher> Drop for PushAuthFlavor<Prev> {
4669    fn drop(&mut self) {
4670        if let Some(prev) = &mut self.prev {
4671            if let Some(header_offset) = &self.header_offset {
4672                finalize_nested_header(prev.as_vec_mut(), *header_offset);
4673            }
4674        }
4675    }
4676}
4677pub struct PushSvcExport<Prev: Pusher> {
4678    pub(crate) prev: Option<Prev>,
4679    pub(crate) header_offset: Option<usize>,
4680}
4681impl<Prev: Pusher> Pusher for PushSvcExport<Prev> {
4682    fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4683        self.prev.as_mut().unwrap().as_vec_mut()
4684    }
4685    fn as_vec(&self) -> &Vec<u8> {
4686        self.prev.as_ref().unwrap().as_vec()
4687    }
4688}
4689impl<Prev: Pusher> PushSvcExport<Prev> {
4690    pub fn new(prev: Prev) -> Self {
4691        Self {
4692            prev: Some(prev),
4693            header_offset: None,
4694        }
4695    }
4696    pub fn end_nested(mut self) -> Prev {
4697        let mut prev = self.prev.take().unwrap();
4698        if let Some(header_offset) = &self.header_offset {
4699            finalize_nested_header(prev.as_vec_mut(), *header_offset);
4700        }
4701        prev
4702    }
4703    pub fn push_seqno(mut self, value: u64) -> Self {
4704        push_header(self.as_vec_mut(), 1u16, 8 as u16);
4705        self.as_vec_mut().extend(value.to_ne_bytes());
4706        self
4707    }
4708    pub fn push_client(mut self, value: &CStr) -> Self {
4709        push_header(
4710            self.as_vec_mut(),
4711            2u16,
4712            value.to_bytes_with_nul().len() as u16,
4713        );
4714        self.as_vec_mut().extend(value.to_bytes_with_nul());
4715        self
4716    }
4717    pub fn push_client_bytes(mut self, value: &[u8]) -> Self {
4718        push_header(self.as_vec_mut(), 2u16, (value.len() + 1) as u16);
4719        self.as_vec_mut().extend(value);
4720        self.as_vec_mut().push(0);
4721        self
4722    }
4723    pub fn push_path(mut self, value: &CStr) -> Self {
4724        push_header(
4725            self.as_vec_mut(),
4726            3u16,
4727            value.to_bytes_with_nul().len() as u16,
4728        );
4729        self.as_vec_mut().extend(value.to_bytes_with_nul());
4730        self
4731    }
4732    pub fn push_path_bytes(mut self, value: &[u8]) -> Self {
4733        push_header(self.as_vec_mut(), 3u16, (value.len() + 1) as u16);
4734        self.as_vec_mut().extend(value);
4735        self.as_vec_mut().push(0);
4736        self
4737    }
4738    pub fn push_negative(mut self, value: ()) -> Self {
4739        push_header(self.as_vec_mut(), 4u16, 0 as u16);
4740        self
4741    }
4742    pub fn push_expiry(mut self, value: u64) -> Self {
4743        push_header(self.as_vec_mut(), 5u16, 8 as u16);
4744        self.as_vec_mut().extend(value.to_ne_bytes());
4745        self
4746    }
4747    pub fn push_anon_uid(mut self, value: u32) -> Self {
4748        push_header(self.as_vec_mut(), 6u16, 4 as u16);
4749        self.as_vec_mut().extend(value.to_ne_bytes());
4750        self
4751    }
4752    pub fn push_anon_gid(mut self, value: u32) -> Self {
4753        push_header(self.as_vec_mut(), 7u16, 4 as u16);
4754        self.as_vec_mut().extend(value.to_ne_bytes());
4755        self
4756    }
4757    pub fn nested_fslocations(mut self) -> PushFslocations<Self> {
4758        let header_offset = push_nested_header(self.as_vec_mut(), 8u16);
4759        PushFslocations {
4760            prev: Some(self),
4761            header_offset: Some(header_offset),
4762        }
4763    }
4764    pub fn push_uuid(mut self, value: &[u8]) -> Self {
4765        push_header(self.as_vec_mut(), 9u16, value.len() as u16);
4766        self.as_vec_mut().extend(value);
4767        self
4768    }
4769    #[doc = "Attribute may repeat multiple times (treat it as array)"]
4770    pub fn nested_secinfo(mut self) -> PushAuthFlavor<Self> {
4771        let header_offset = push_nested_header(self.as_vec_mut(), 10u16);
4772        PushAuthFlavor {
4773            prev: Some(self),
4774            header_offset: Some(header_offset),
4775        }
4776    }
4777    #[doc = "Associated type: [`XprtsecMode`] (enum)\nAttribute may repeat multiple times (treat it as array)"]
4778    pub fn push_xprtsec(mut self, value: u32) -> Self {
4779        push_header(self.as_vec_mut(), 11u16, 4 as u16);
4780        self.as_vec_mut().extend(value.to_ne_bytes());
4781        self
4782    }
4783    #[doc = "Associated type: [`ExportFlags`] (1 bit per enumeration)"]
4784    pub fn push_flags(mut self, value: u32) -> Self {
4785        push_header(self.as_vec_mut(), 12u16, 4 as u16);
4786        self.as_vec_mut().extend(value.to_ne_bytes());
4787        self
4788    }
4789    pub fn push_fsid(mut self, value: i32) -> Self {
4790        push_header(self.as_vec_mut(), 13u16, 4 as u16);
4791        self.as_vec_mut().extend(value.to_ne_bytes());
4792        self
4793    }
4794}
4795impl<Prev: Pusher> Drop for PushSvcExport<Prev> {
4796    fn drop(&mut self) {
4797        if let Some(prev) = &mut self.prev {
4798            if let Some(header_offset) = &self.header_offset {
4799                finalize_nested_header(prev.as_vec_mut(), *header_offset);
4800            }
4801        }
4802    }
4803}
4804pub struct PushSvcExportReqs<Prev: Pusher> {
4805    pub(crate) prev: Option<Prev>,
4806    pub(crate) header_offset: Option<usize>,
4807}
4808impl<Prev: Pusher> Pusher for PushSvcExportReqs<Prev> {
4809    fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4810        self.prev.as_mut().unwrap().as_vec_mut()
4811    }
4812    fn as_vec(&self) -> &Vec<u8> {
4813        self.prev.as_ref().unwrap().as_vec()
4814    }
4815}
4816impl<Prev: Pusher> PushSvcExportReqs<Prev> {
4817    pub fn new(prev: Prev) -> Self {
4818        Self {
4819            prev: Some(prev),
4820            header_offset: None,
4821        }
4822    }
4823    pub fn end_nested(mut self) -> Prev {
4824        let mut prev = self.prev.take().unwrap();
4825        if let Some(header_offset) = &self.header_offset {
4826            finalize_nested_header(prev.as_vec_mut(), *header_offset);
4827        }
4828        prev
4829    }
4830    #[doc = "Attribute may repeat multiple times (treat it as array)"]
4831    pub fn nested_requests(mut self) -> PushSvcExport<Self> {
4832        let header_offset = push_nested_header(self.as_vec_mut(), 1u16);
4833        PushSvcExport {
4834            prev: Some(self),
4835            header_offset: Some(header_offset),
4836        }
4837    }
4838}
4839impl<Prev: Pusher> Drop for PushSvcExportReqs<Prev> {
4840    fn drop(&mut self) {
4841        if let Some(prev) = &mut self.prev {
4842            if let Some(header_offset) = &self.header_offset {
4843                finalize_nested_header(prev.as_vec_mut(), *header_offset);
4844            }
4845        }
4846    }
4847}
4848pub struct PushExpkey<Prev: Pusher> {
4849    pub(crate) prev: Option<Prev>,
4850    pub(crate) header_offset: Option<usize>,
4851}
4852impl<Prev: Pusher> Pusher for PushExpkey<Prev> {
4853    fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4854        self.prev.as_mut().unwrap().as_vec_mut()
4855    }
4856    fn as_vec(&self) -> &Vec<u8> {
4857        self.prev.as_ref().unwrap().as_vec()
4858    }
4859}
4860impl<Prev: Pusher> PushExpkey<Prev> {
4861    pub fn new(prev: Prev) -> Self {
4862        Self {
4863            prev: Some(prev),
4864            header_offset: None,
4865        }
4866    }
4867    pub fn end_nested(mut self) -> Prev {
4868        let mut prev = self.prev.take().unwrap();
4869        if let Some(header_offset) = &self.header_offset {
4870            finalize_nested_header(prev.as_vec_mut(), *header_offset);
4871        }
4872        prev
4873    }
4874    pub fn push_seqno(mut self, value: u64) -> Self {
4875        push_header(self.as_vec_mut(), 1u16, 8 as u16);
4876        self.as_vec_mut().extend(value.to_ne_bytes());
4877        self
4878    }
4879    pub fn push_client(mut self, value: &CStr) -> Self {
4880        push_header(
4881            self.as_vec_mut(),
4882            2u16,
4883            value.to_bytes_with_nul().len() as u16,
4884        );
4885        self.as_vec_mut().extend(value.to_bytes_with_nul());
4886        self
4887    }
4888    pub fn push_client_bytes(mut self, value: &[u8]) -> Self {
4889        push_header(self.as_vec_mut(), 2u16, (value.len() + 1) as u16);
4890        self.as_vec_mut().extend(value);
4891        self.as_vec_mut().push(0);
4892        self
4893    }
4894    pub fn push_fsidtype(mut self, value: u8) -> Self {
4895        push_header(self.as_vec_mut(), 3u16, 1 as u16);
4896        self.as_vec_mut().extend(value.to_ne_bytes());
4897        self
4898    }
4899    pub fn push_fsid(mut self, value: &[u8]) -> Self {
4900        push_header(self.as_vec_mut(), 4u16, value.len() as u16);
4901        self.as_vec_mut().extend(value);
4902        self
4903    }
4904    pub fn push_negative(mut self, value: ()) -> Self {
4905        push_header(self.as_vec_mut(), 5u16, 0 as u16);
4906        self
4907    }
4908    pub fn push_expiry(mut self, value: u64) -> Self {
4909        push_header(self.as_vec_mut(), 6u16, 8 as u16);
4910        self.as_vec_mut().extend(value.to_ne_bytes());
4911        self
4912    }
4913    pub fn push_path(mut self, value: &CStr) -> Self {
4914        push_header(
4915            self.as_vec_mut(),
4916            7u16,
4917            value.to_bytes_with_nul().len() as u16,
4918        );
4919        self.as_vec_mut().extend(value.to_bytes_with_nul());
4920        self
4921    }
4922    pub fn push_path_bytes(mut self, value: &[u8]) -> Self {
4923        push_header(self.as_vec_mut(), 7u16, (value.len() + 1) as u16);
4924        self.as_vec_mut().extend(value);
4925        self.as_vec_mut().push(0);
4926        self
4927    }
4928}
4929impl<Prev: Pusher> Drop for PushExpkey<Prev> {
4930    fn drop(&mut self) {
4931        if let Some(prev) = &mut self.prev {
4932            if let Some(header_offset) = &self.header_offset {
4933                finalize_nested_header(prev.as_vec_mut(), *header_offset);
4934            }
4935        }
4936    }
4937}
4938pub struct PushExpkeyReqs<Prev: Pusher> {
4939    pub(crate) prev: Option<Prev>,
4940    pub(crate) header_offset: Option<usize>,
4941}
4942impl<Prev: Pusher> Pusher for PushExpkeyReqs<Prev> {
4943    fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4944        self.prev.as_mut().unwrap().as_vec_mut()
4945    }
4946    fn as_vec(&self) -> &Vec<u8> {
4947        self.prev.as_ref().unwrap().as_vec()
4948    }
4949}
4950impl<Prev: Pusher> PushExpkeyReqs<Prev> {
4951    pub fn new(prev: Prev) -> Self {
4952        Self {
4953            prev: Some(prev),
4954            header_offset: None,
4955        }
4956    }
4957    pub fn end_nested(mut self) -> Prev {
4958        let mut prev = self.prev.take().unwrap();
4959        if let Some(header_offset) = &self.header_offset {
4960            finalize_nested_header(prev.as_vec_mut(), *header_offset);
4961        }
4962        prev
4963    }
4964    #[doc = "Attribute may repeat multiple times (treat it as array)"]
4965    pub fn nested_requests(mut self) -> PushExpkey<Self> {
4966        let header_offset = push_nested_header(self.as_vec_mut(), 1u16);
4967        PushExpkey {
4968            prev: Some(self),
4969            header_offset: Some(header_offset),
4970        }
4971    }
4972}
4973impl<Prev: Pusher> Drop for PushExpkeyReqs<Prev> {
4974    fn drop(&mut self) {
4975        if let Some(prev) = &mut self.prev {
4976            if let Some(header_offset) = &self.header_offset {
4977                finalize_nested_header(prev.as_vec_mut(), *header_offset);
4978            }
4979        }
4980    }
4981}
4982pub struct PushCacheFlush<Prev: Pusher> {
4983    pub(crate) prev: Option<Prev>,
4984    pub(crate) header_offset: Option<usize>,
4985}
4986impl<Prev: Pusher> Pusher for PushCacheFlush<Prev> {
4987    fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4988        self.prev.as_mut().unwrap().as_vec_mut()
4989    }
4990    fn as_vec(&self) -> &Vec<u8> {
4991        self.prev.as_ref().unwrap().as_vec()
4992    }
4993}
4994impl<Prev: Pusher> PushCacheFlush<Prev> {
4995    pub fn new(prev: Prev) -> Self {
4996        Self {
4997            prev: Some(prev),
4998            header_offset: None,
4999        }
5000    }
5001    pub fn end_nested(mut self) -> Prev {
5002        let mut prev = self.prev.take().unwrap();
5003        if let Some(header_offset) = &self.header_offset {
5004            finalize_nested_header(prev.as_vec_mut(), *header_offset);
5005        }
5006        prev
5007    }
5008    #[doc = "Associated type: [`CacheType`] (1 bit per enumeration)"]
5009    pub fn push_mask(mut self, value: u32) -> Self {
5010        push_header(self.as_vec_mut(), 1u16, 4 as u16);
5011        self.as_vec_mut().extend(value.to_ne_bytes());
5012        self
5013    }
5014}
5015impl<Prev: Pusher> Drop for PushCacheFlush<Prev> {
5016    fn drop(&mut self) {
5017        if let Some(prev) = &mut self.prev {
5018            if let Some(header_offset) = &self.header_offset {
5019                finalize_nested_header(prev.as_vec_mut(), *header_offset);
5020            }
5021        }
5022    }
5023}
5024pub struct PushUnlockIp<Prev: Pusher> {
5025    pub(crate) prev: Option<Prev>,
5026    pub(crate) header_offset: Option<usize>,
5027}
5028impl<Prev: Pusher> Pusher for PushUnlockIp<Prev> {
5029    fn as_vec_mut(&mut self) -> &mut Vec<u8> {
5030        self.prev.as_mut().unwrap().as_vec_mut()
5031    }
5032    fn as_vec(&self) -> &Vec<u8> {
5033        self.prev.as_ref().unwrap().as_vec()
5034    }
5035}
5036impl<Prev: Pusher> PushUnlockIp<Prev> {
5037    pub fn new(prev: Prev) -> Self {
5038        Self {
5039            prev: Some(prev),
5040            header_offset: None,
5041        }
5042    }
5043    pub fn end_nested(mut self) -> Prev {
5044        let mut prev = self.prev.take().unwrap();
5045        if let Some(header_offset) = &self.header_offset {
5046            finalize_nested_header(prev.as_vec_mut(), *header_offset);
5047        }
5048        prev
5049    }
5050    #[doc = "struct sockaddr_in or struct sockaddr_in6.\n"]
5051    pub fn push_address(mut self, value: &[u8]) -> Self {
5052        push_header(self.as_vec_mut(), 1u16, value.len() as u16);
5053        self.as_vec_mut().extend(value);
5054        self
5055    }
5056}
5057impl<Prev: Pusher> Drop for PushUnlockIp<Prev> {
5058    fn drop(&mut self) {
5059        if let Some(prev) = &mut self.prev {
5060            if let Some(header_offset) = &self.header_offset {
5061                finalize_nested_header(prev.as_vec_mut(), *header_offset);
5062            }
5063        }
5064    }
5065}
5066pub struct PushUnlockFilesystem<Prev: Pusher> {
5067    pub(crate) prev: Option<Prev>,
5068    pub(crate) header_offset: Option<usize>,
5069}
5070impl<Prev: Pusher> Pusher for PushUnlockFilesystem<Prev> {
5071    fn as_vec_mut(&mut self) -> &mut Vec<u8> {
5072        self.prev.as_mut().unwrap().as_vec_mut()
5073    }
5074    fn as_vec(&self) -> &Vec<u8> {
5075        self.prev.as_ref().unwrap().as_vec()
5076    }
5077}
5078impl<Prev: Pusher> PushUnlockFilesystem<Prev> {
5079    pub fn new(prev: Prev) -> Self {
5080        Self {
5081            prev: Some(prev),
5082            header_offset: None,
5083        }
5084    }
5085    pub fn end_nested(mut self) -> Prev {
5086        let mut prev = self.prev.take().unwrap();
5087        if let Some(header_offset) = &self.header_offset {
5088            finalize_nested_header(prev.as_vec_mut(), *header_offset);
5089        }
5090        prev
5091    }
5092    #[doc = "Filesystem path whose state should be released.\n"]
5093    pub fn push_path(mut self, value: &CStr) -> Self {
5094        push_header(
5095            self.as_vec_mut(),
5096            1u16,
5097            value.to_bytes_with_nul().len() as u16,
5098        );
5099        self.as_vec_mut().extend(value.to_bytes_with_nul());
5100        self
5101    }
5102    #[doc = "Filesystem path whose state should be released.\n"]
5103    pub fn push_path_bytes(mut self, value: &[u8]) -> Self {
5104        push_header(self.as_vec_mut(), 1u16, (value.len() + 1) as u16);
5105        self.as_vec_mut().extend(value);
5106        self.as_vec_mut().push(0);
5107        self
5108    }
5109}
5110impl<Prev: Pusher> Drop for PushUnlockFilesystem<Prev> {
5111    fn drop(&mut self) {
5112        if let Some(prev) = &mut self.prev {
5113            if let Some(header_offset) = &self.header_offset {
5114                finalize_nested_header(prev.as_vec_mut(), *header_offset);
5115            }
5116        }
5117    }
5118}
5119pub struct PushUnlockExport<Prev: Pusher> {
5120    pub(crate) prev: Option<Prev>,
5121    pub(crate) header_offset: Option<usize>,
5122}
5123impl<Prev: Pusher> Pusher for PushUnlockExport<Prev> {
5124    fn as_vec_mut(&mut self) -> &mut Vec<u8> {
5125        self.prev.as_mut().unwrap().as_vec_mut()
5126    }
5127    fn as_vec(&self) -> &Vec<u8> {
5128        self.prev.as_ref().unwrap().as_vec()
5129    }
5130}
5131impl<Prev: Pusher> PushUnlockExport<Prev> {
5132    pub fn new(prev: Prev) -> Self {
5133        Self {
5134            prev: Some(prev),
5135            header_offset: None,
5136        }
5137    }
5138    pub fn end_nested(mut self) -> Prev {
5139        let mut prev = self.prev.take().unwrap();
5140        if let Some(header_offset) = &self.header_offset {
5141            finalize_nested_header(prev.as_vec_mut(), *header_offset);
5142        }
5143        prev
5144    }
5145    #[doc = "Export path whose NFSv4 state should be revoked. All state (opens,\nlocks, delegations, layouts) acquired through any export of this path is\nrevoked, regardless of which client holds the state. Intended for use\nafter all clients have been unexported from a given path, enabling the\nunderlying filesystem to be unmounted.\n"]
5146    pub fn push_path(mut self, value: &CStr) -> Self {
5147        push_header(
5148            self.as_vec_mut(),
5149            1u16,
5150            value.to_bytes_with_nul().len() as u16,
5151        );
5152        self.as_vec_mut().extend(value.to_bytes_with_nul());
5153        self
5154    }
5155    #[doc = "Export path whose NFSv4 state should be revoked. All state (opens,\nlocks, delegations, layouts) acquired through any export of this path is\nrevoked, regardless of which client holds the state. Intended for use\nafter all clients have been unexported from a given path, enabling the\nunderlying filesystem to be unmounted.\n"]
5156    pub fn push_path_bytes(mut self, value: &[u8]) -> Self {
5157        push_header(self.as_vec_mut(), 1u16, (value.len() + 1) as u16);
5158        self.as_vec_mut().extend(value);
5159        self.as_vec_mut().push(0);
5160        self
5161    }
5162}
5163impl<Prev: Pusher> Drop for PushUnlockExport<Prev> {
5164    fn drop(&mut self) {
5165        if let Some(prev) = &mut self.prev {
5166            if let Some(header_offset) = &self.header_offset {
5167                finalize_nested_header(prev.as_vec_mut(), *header_offset);
5168            }
5169        }
5170    }
5171}
5172#[doc = "Notify attributes:\n- [`.get_cache_type()`](IterableCacheNotify::get_cache_type)\n"]
5173#[derive(Debug)]
5174pub struct OpCacheNotifyNotif;
5175impl OpCacheNotifyNotif {
5176    pub const CMD: u8 = 10u8;
5177    pub fn decode_notif<'a>(buf: &'a [u8]) -> IterableCacheNotify<'a> {
5178        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5179        IterableCacheNotify::with_loc(attrs, buf.as_ptr() as usize)
5180    }
5181}
5182pub struct NotifGroup;
5183impl NotifGroup {
5184    pub const NONE: &str = "none";
5185    pub const NONE_CSTR: &CStr = c"none";
5186    #[doc = "Notifications:\n- [`OpCacheNotifyNotif`]\n"]
5187    pub const EXPORTD: &str = "exportd";
5188    #[doc = "Notifications:\n- [`OpCacheNotifyNotif`]\n"]
5189    pub const EXPORTD_CSTR: &CStr = c"exportd";
5190}
5191#[doc = "dump pending nfsd rpc\n\nReply attributes:\n- [.get_xid()](IterableRpcStatus::get_xid)\n- [.get_flags()](IterableRpcStatus::get_flags)\n- [.get_prog()](IterableRpcStatus::get_prog)\n- [.get_version()](IterableRpcStatus::get_version)\n- [.get_proc()](IterableRpcStatus::get_proc)\n- [.get_service_time()](IterableRpcStatus::get_service_time)\n- [.get_saddr4()](IterableRpcStatus::get_saddr4)\n- [.get_daddr4()](IterableRpcStatus::get_daddr4)\n- [.get_saddr6()](IterableRpcStatus::get_saddr6)\n- [.get_daddr6()](IterableRpcStatus::get_daddr6)\n- [.get_sport()](IterableRpcStatus::get_sport)\n- [.get_dport()](IterableRpcStatus::get_dport)\n- [.get_compound_ops()](IterableRpcStatus::get_compound_ops)\n\n"]
5192#[derive(Debug)]
5193pub struct OpRpcStatusGetDump<'r> {
5194    request: Request<'r>,
5195}
5196impl<'r> OpRpcStatusGetDump<'r> {
5197    pub fn new(mut request: Request<'r>) -> Self {
5198        Self::write_header(request.buf_mut());
5199        Self {
5200            request: request.set_dump(),
5201        }
5202    }
5203    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushRpcStatus<&'buf mut Vec<u8>> {
5204        Self::write_header(buf);
5205        PushRpcStatus::new(buf)
5206    }
5207    pub fn encode(&mut self) -> PushRpcStatus<&mut Vec<u8>> {
5208        PushRpcStatus::new(self.request.buf_mut())
5209    }
5210    pub fn into_encoder(self) -> PushRpcStatus<RequestBuf<'r>> {
5211        PushRpcStatus::new(self.request.buf)
5212    }
5213    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableRpcStatus<'a> {
5214        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5215        IterableRpcStatus::with_loc(attrs, buf.as_ptr() as usize)
5216    }
5217    fn write_header<Prev: Pusher>(prev: &mut Prev) {
5218        let mut header = BuiltinNfgenmsg::new();
5219        header.cmd = 1u8;
5220        header.version = 1u8;
5221        prev.as_vec_mut().extend(header.as_slice());
5222    }
5223}
5224impl NetlinkRequest for OpRpcStatusGetDump<'_> {
5225    fn protocol(&self) -> Protocol {
5226        Protocol::Generic("nfsd".as_bytes())
5227    }
5228    fn flags(&self) -> u16 {
5229        self.request.flags
5230    }
5231    fn payload(&self) -> &[u8] {
5232        self.request.buf()
5233    }
5234    type ReplyType<'buf> = IterableRpcStatus<'buf>;
5235    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5236        Self::decode_request(buf)
5237    }
5238    fn lookup(
5239        buf: &[u8],
5240        offset: usize,
5241        missing_type: Option<u16>,
5242    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5243        Self::decode_request(buf).lookup_attr(offset, missing_type)
5244    }
5245}
5246#[doc = "set the maximum number of running threads\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_threads()](PushServer::push_threads)\n- [.push_gracetime()](PushServer::push_gracetime)\n- [.push_leasetime()](PushServer::push_leasetime)\n- [.push_scope()](PushServer::push_scope)\n- [.push_min_threads()](PushServer::push_min_threads)\n- [.push_fh_key()](PushServer::push_fh_key)\n\n"]
5247#[derive(Debug)]
5248pub struct OpThreadsSetDo<'r> {
5249    request: Request<'r>,
5250}
5251impl<'r> OpThreadsSetDo<'r> {
5252    pub fn new(mut request: Request<'r>) -> Self {
5253        Self::write_header(request.buf_mut());
5254        Self { request: request }
5255    }
5256    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushServer<&'buf mut Vec<u8>> {
5257        Self::write_header(buf);
5258        PushServer::new(buf)
5259    }
5260    pub fn encode(&mut self) -> PushServer<&mut Vec<u8>> {
5261        PushServer::new(self.request.buf_mut())
5262    }
5263    pub fn into_encoder(self) -> PushServer<RequestBuf<'r>> {
5264        PushServer::new(self.request.buf)
5265    }
5266    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableServer<'a> {
5267        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5268        IterableServer::with_loc(attrs, buf.as_ptr() as usize)
5269    }
5270    fn write_header<Prev: Pusher>(prev: &mut Prev) {
5271        let mut header = BuiltinNfgenmsg::new();
5272        header.cmd = 2u8;
5273        header.version = 1u8;
5274        prev.as_vec_mut().extend(header.as_slice());
5275    }
5276}
5277impl NetlinkRequest for OpThreadsSetDo<'_> {
5278    fn protocol(&self) -> Protocol {
5279        Protocol::Generic("nfsd".as_bytes())
5280    }
5281    fn flags(&self) -> u16 {
5282        self.request.flags
5283    }
5284    fn payload(&self) -> &[u8] {
5285        self.request.buf()
5286    }
5287    type ReplyType<'buf> = IterableServer<'buf>;
5288    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5289        Self::decode_request(buf)
5290    }
5291    fn lookup(
5292        buf: &[u8],
5293        offset: usize,
5294        missing_type: Option<u16>,
5295    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5296        Self::decode_request(buf).lookup_attr(offset, missing_type)
5297    }
5298}
5299#[doc = "get the maximum number of running threads\n\nReply attributes:\n- [.get_threads()](IterableServer::get_threads)\n- [.get_gracetime()](IterableServer::get_gracetime)\n- [.get_leasetime()](IterableServer::get_leasetime)\n- [.get_scope()](IterableServer::get_scope)\n- [.get_min_threads()](IterableServer::get_min_threads)\n\n"]
5300#[derive(Debug)]
5301pub struct OpThreadsGetDo<'r> {
5302    request: Request<'r>,
5303}
5304impl<'r> OpThreadsGetDo<'r> {
5305    pub fn new(mut request: Request<'r>) -> Self {
5306        Self::write_header(request.buf_mut());
5307        Self { request: request }
5308    }
5309    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushServer<&'buf mut Vec<u8>> {
5310        Self::write_header(buf);
5311        PushServer::new(buf)
5312    }
5313    pub fn encode(&mut self) -> PushServer<&mut Vec<u8>> {
5314        PushServer::new(self.request.buf_mut())
5315    }
5316    pub fn into_encoder(self) -> PushServer<RequestBuf<'r>> {
5317        PushServer::new(self.request.buf)
5318    }
5319    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableServer<'a> {
5320        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5321        IterableServer::with_loc(attrs, buf.as_ptr() as usize)
5322    }
5323    fn write_header<Prev: Pusher>(prev: &mut Prev) {
5324        let mut header = BuiltinNfgenmsg::new();
5325        header.cmd = 3u8;
5326        header.version = 1u8;
5327        prev.as_vec_mut().extend(header.as_slice());
5328    }
5329}
5330impl NetlinkRequest for OpThreadsGetDo<'_> {
5331    fn protocol(&self) -> Protocol {
5332        Protocol::Generic("nfsd".as_bytes())
5333    }
5334    fn flags(&self) -> u16 {
5335        self.request.flags
5336    }
5337    fn payload(&self) -> &[u8] {
5338        self.request.buf()
5339    }
5340    type ReplyType<'buf> = IterableServer<'buf>;
5341    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5342        Self::decode_request(buf)
5343    }
5344    fn lookup(
5345        buf: &[u8],
5346        offset: usize,
5347        missing_type: Option<u16>,
5348    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5349        Self::decode_request(buf).lookup_attr(offset, missing_type)
5350    }
5351}
5352#[doc = "set nfs enabled versions\n\nFlags: admin-perm\n\nRequest attributes:\n- [.nested_version()](PushServerProto::nested_version)\n\n"]
5353#[derive(Debug)]
5354pub struct OpVersionSetDo<'r> {
5355    request: Request<'r>,
5356}
5357impl<'r> OpVersionSetDo<'r> {
5358    pub fn new(mut request: Request<'r>) -> Self {
5359        Self::write_header(request.buf_mut());
5360        Self { request: request }
5361    }
5362    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushServerProto<&'buf mut Vec<u8>> {
5363        Self::write_header(buf);
5364        PushServerProto::new(buf)
5365    }
5366    pub fn encode(&mut self) -> PushServerProto<&mut Vec<u8>> {
5367        PushServerProto::new(self.request.buf_mut())
5368    }
5369    pub fn into_encoder(self) -> PushServerProto<RequestBuf<'r>> {
5370        PushServerProto::new(self.request.buf)
5371    }
5372    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableServerProto<'a> {
5373        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5374        IterableServerProto::with_loc(attrs, buf.as_ptr() as usize)
5375    }
5376    fn write_header<Prev: Pusher>(prev: &mut Prev) {
5377        let mut header = BuiltinNfgenmsg::new();
5378        header.cmd = 4u8;
5379        header.version = 1u8;
5380        prev.as_vec_mut().extend(header.as_slice());
5381    }
5382}
5383impl NetlinkRequest for OpVersionSetDo<'_> {
5384    fn protocol(&self) -> Protocol {
5385        Protocol::Generic("nfsd".as_bytes())
5386    }
5387    fn flags(&self) -> u16 {
5388        self.request.flags
5389    }
5390    fn payload(&self) -> &[u8] {
5391        self.request.buf()
5392    }
5393    type ReplyType<'buf> = IterableServerProto<'buf>;
5394    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5395        Self::decode_request(buf)
5396    }
5397    fn lookup(
5398        buf: &[u8],
5399        offset: usize,
5400        missing_type: Option<u16>,
5401    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5402        Self::decode_request(buf).lookup_attr(offset, missing_type)
5403    }
5404}
5405#[doc = "get nfs enabled versions\n\nReply attributes:\n- [.get_version()](IterableServerProto::get_version)\n\n"]
5406#[derive(Debug)]
5407pub struct OpVersionGetDo<'r> {
5408    request: Request<'r>,
5409}
5410impl<'r> OpVersionGetDo<'r> {
5411    pub fn new(mut request: Request<'r>) -> Self {
5412        Self::write_header(request.buf_mut());
5413        Self { request: request }
5414    }
5415    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushServerProto<&'buf mut Vec<u8>> {
5416        Self::write_header(buf);
5417        PushServerProto::new(buf)
5418    }
5419    pub fn encode(&mut self) -> PushServerProto<&mut Vec<u8>> {
5420        PushServerProto::new(self.request.buf_mut())
5421    }
5422    pub fn into_encoder(self) -> PushServerProto<RequestBuf<'r>> {
5423        PushServerProto::new(self.request.buf)
5424    }
5425    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableServerProto<'a> {
5426        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5427        IterableServerProto::with_loc(attrs, buf.as_ptr() as usize)
5428    }
5429    fn write_header<Prev: Pusher>(prev: &mut Prev) {
5430        let mut header = BuiltinNfgenmsg::new();
5431        header.cmd = 5u8;
5432        header.version = 1u8;
5433        prev.as_vec_mut().extend(header.as_slice());
5434    }
5435}
5436impl NetlinkRequest for OpVersionGetDo<'_> {
5437    fn protocol(&self) -> Protocol {
5438        Protocol::Generic("nfsd".as_bytes())
5439    }
5440    fn flags(&self) -> u16 {
5441        self.request.flags
5442    }
5443    fn payload(&self) -> &[u8] {
5444        self.request.buf()
5445    }
5446    type ReplyType<'buf> = IterableServerProto<'buf>;
5447    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5448        Self::decode_request(buf)
5449    }
5450    fn lookup(
5451        buf: &[u8],
5452        offset: usize,
5453        missing_type: Option<u16>,
5454    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5455        Self::decode_request(buf).lookup_attr(offset, missing_type)
5456    }
5457}
5458#[doc = "set nfs running sockets\n\nFlags: admin-perm\n\nRequest attributes:\n- [.nested_addr()](PushServerSock::nested_addr)\n\n"]
5459#[derive(Debug)]
5460pub struct OpListenerSetDo<'r> {
5461    request: Request<'r>,
5462}
5463impl<'r> OpListenerSetDo<'r> {
5464    pub fn new(mut request: Request<'r>) -> Self {
5465        Self::write_header(request.buf_mut());
5466        Self { request: request }
5467    }
5468    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushServerSock<&'buf mut Vec<u8>> {
5469        Self::write_header(buf);
5470        PushServerSock::new(buf)
5471    }
5472    pub fn encode(&mut self) -> PushServerSock<&mut Vec<u8>> {
5473        PushServerSock::new(self.request.buf_mut())
5474    }
5475    pub fn into_encoder(self) -> PushServerSock<RequestBuf<'r>> {
5476        PushServerSock::new(self.request.buf)
5477    }
5478    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableServerSock<'a> {
5479        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5480        IterableServerSock::with_loc(attrs, buf.as_ptr() as usize)
5481    }
5482    fn write_header<Prev: Pusher>(prev: &mut Prev) {
5483        let mut header = BuiltinNfgenmsg::new();
5484        header.cmd = 6u8;
5485        header.version = 1u8;
5486        prev.as_vec_mut().extend(header.as_slice());
5487    }
5488}
5489impl NetlinkRequest for OpListenerSetDo<'_> {
5490    fn protocol(&self) -> Protocol {
5491        Protocol::Generic("nfsd".as_bytes())
5492    }
5493    fn flags(&self) -> u16 {
5494        self.request.flags
5495    }
5496    fn payload(&self) -> &[u8] {
5497        self.request.buf()
5498    }
5499    type ReplyType<'buf> = IterableServerSock<'buf>;
5500    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5501        Self::decode_request(buf)
5502    }
5503    fn lookup(
5504        buf: &[u8],
5505        offset: usize,
5506        missing_type: Option<u16>,
5507    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5508        Self::decode_request(buf).lookup_attr(offset, missing_type)
5509    }
5510}
5511#[doc = "get nfs running listeners\n\nReply attributes:\n- [.get_addr()](IterableServerSock::get_addr)\n\n"]
5512#[derive(Debug)]
5513pub struct OpListenerGetDo<'r> {
5514    request: Request<'r>,
5515}
5516impl<'r> OpListenerGetDo<'r> {
5517    pub fn new(mut request: Request<'r>) -> Self {
5518        Self::write_header(request.buf_mut());
5519        Self { request: request }
5520    }
5521    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushServerSock<&'buf mut Vec<u8>> {
5522        Self::write_header(buf);
5523        PushServerSock::new(buf)
5524    }
5525    pub fn encode(&mut self) -> PushServerSock<&mut Vec<u8>> {
5526        PushServerSock::new(self.request.buf_mut())
5527    }
5528    pub fn into_encoder(self) -> PushServerSock<RequestBuf<'r>> {
5529        PushServerSock::new(self.request.buf)
5530    }
5531    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableServerSock<'a> {
5532        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5533        IterableServerSock::with_loc(attrs, buf.as_ptr() as usize)
5534    }
5535    fn write_header<Prev: Pusher>(prev: &mut Prev) {
5536        let mut header = BuiltinNfgenmsg::new();
5537        header.cmd = 7u8;
5538        header.version = 1u8;
5539        prev.as_vec_mut().extend(header.as_slice());
5540    }
5541}
5542impl NetlinkRequest for OpListenerGetDo<'_> {
5543    fn protocol(&self) -> Protocol {
5544        Protocol::Generic("nfsd".as_bytes())
5545    }
5546    fn flags(&self) -> u16 {
5547        self.request.flags
5548    }
5549    fn payload(&self) -> &[u8] {
5550        self.request.buf()
5551    }
5552    type ReplyType<'buf> = IterableServerSock<'buf>;
5553    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5554        Self::decode_request(buf)
5555    }
5556    fn lookup(
5557        buf: &[u8],
5558        offset: usize,
5559        missing_type: Option<u16>,
5560    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5561        Self::decode_request(buf).lookup_attr(offset, missing_type)
5562    }
5563}
5564#[doc = "set the current server pool-mode\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_mode()](PushPoolMode::push_mode)\n\n"]
5565#[derive(Debug)]
5566pub struct OpPoolModeSetDo<'r> {
5567    request: Request<'r>,
5568}
5569impl<'r> OpPoolModeSetDo<'r> {
5570    pub fn new(mut request: Request<'r>) -> Self {
5571        Self::write_header(request.buf_mut());
5572        Self { request: request }
5573    }
5574    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushPoolMode<&'buf mut Vec<u8>> {
5575        Self::write_header(buf);
5576        PushPoolMode::new(buf)
5577    }
5578    pub fn encode(&mut self) -> PushPoolMode<&mut Vec<u8>> {
5579        PushPoolMode::new(self.request.buf_mut())
5580    }
5581    pub fn into_encoder(self) -> PushPoolMode<RequestBuf<'r>> {
5582        PushPoolMode::new(self.request.buf)
5583    }
5584    pub fn decode_request<'a>(buf: &'a [u8]) -> IterablePoolMode<'a> {
5585        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5586        IterablePoolMode::with_loc(attrs, buf.as_ptr() as usize)
5587    }
5588    fn write_header<Prev: Pusher>(prev: &mut Prev) {
5589        let mut header = BuiltinNfgenmsg::new();
5590        header.cmd = 8u8;
5591        header.version = 1u8;
5592        prev.as_vec_mut().extend(header.as_slice());
5593    }
5594}
5595impl NetlinkRequest for OpPoolModeSetDo<'_> {
5596    fn protocol(&self) -> Protocol {
5597        Protocol::Generic("nfsd".as_bytes())
5598    }
5599    fn flags(&self) -> u16 {
5600        self.request.flags
5601    }
5602    fn payload(&self) -> &[u8] {
5603        self.request.buf()
5604    }
5605    type ReplyType<'buf> = IterablePoolMode<'buf>;
5606    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5607        Self::decode_request(buf)
5608    }
5609    fn lookup(
5610        buf: &[u8],
5611        offset: usize,
5612        missing_type: Option<u16>,
5613    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5614        Self::decode_request(buf).lookup_attr(offset, missing_type)
5615    }
5616}
5617#[doc = "get info about server pool-mode\n\nReply attributes:\n- [.get_mode()](IterablePoolMode::get_mode)\n- [.get_npools()](IterablePoolMode::get_npools)\n\n"]
5618#[derive(Debug)]
5619pub struct OpPoolModeGetDo<'r> {
5620    request: Request<'r>,
5621}
5622impl<'r> OpPoolModeGetDo<'r> {
5623    pub fn new(mut request: Request<'r>) -> Self {
5624        Self::write_header(request.buf_mut());
5625        Self { request: request }
5626    }
5627    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushPoolMode<&'buf mut Vec<u8>> {
5628        Self::write_header(buf);
5629        PushPoolMode::new(buf)
5630    }
5631    pub fn encode(&mut self) -> PushPoolMode<&mut Vec<u8>> {
5632        PushPoolMode::new(self.request.buf_mut())
5633    }
5634    pub fn into_encoder(self) -> PushPoolMode<RequestBuf<'r>> {
5635        PushPoolMode::new(self.request.buf)
5636    }
5637    pub fn decode_request<'a>(buf: &'a [u8]) -> IterablePoolMode<'a> {
5638        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5639        IterablePoolMode::with_loc(attrs, buf.as_ptr() as usize)
5640    }
5641    fn write_header<Prev: Pusher>(prev: &mut Prev) {
5642        let mut header = BuiltinNfgenmsg::new();
5643        header.cmd = 9u8;
5644        header.version = 1u8;
5645        prev.as_vec_mut().extend(header.as_slice());
5646    }
5647}
5648impl NetlinkRequest for OpPoolModeGetDo<'_> {
5649    fn protocol(&self) -> Protocol {
5650        Protocol::Generic("nfsd".as_bytes())
5651    }
5652    fn flags(&self) -> u16 {
5653        self.request.flags
5654    }
5655    fn payload(&self) -> &[u8] {
5656        self.request.buf()
5657    }
5658    type ReplyType<'buf> = IterablePoolMode<'buf>;
5659    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5660        Self::decode_request(buf)
5661    }
5662    fn lookup(
5663        buf: &[u8],
5664        offset: usize,
5665        missing_type: Option<u16>,
5666    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5667        Self::decode_request(buf).lookup_attr(offset, missing_type)
5668    }
5669}
5670#[doc = "Dump all pending svc_export requests\n\nFlags: admin-perm\n\nReply attributes:\n- [.get_requests()](IterableSvcExportReqs::get_requests)\n\n"]
5671#[derive(Debug)]
5672pub struct OpSvcExportGetReqsDump<'r> {
5673    request: Request<'r>,
5674}
5675impl<'r> OpSvcExportGetReqsDump<'r> {
5676    pub fn new(mut request: Request<'r>) -> Self {
5677        Self::write_header(request.buf_mut());
5678        Self {
5679            request: request.set_dump(),
5680        }
5681    }
5682    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushSvcExportReqs<&'buf mut Vec<u8>> {
5683        Self::write_header(buf);
5684        PushSvcExportReqs::new(buf)
5685    }
5686    pub fn encode(&mut self) -> PushSvcExportReqs<&mut Vec<u8>> {
5687        PushSvcExportReqs::new(self.request.buf_mut())
5688    }
5689    pub fn into_encoder(self) -> PushSvcExportReqs<RequestBuf<'r>> {
5690        PushSvcExportReqs::new(self.request.buf)
5691    }
5692    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableSvcExportReqs<'a> {
5693        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5694        IterableSvcExportReqs::with_loc(attrs, buf.as_ptr() as usize)
5695    }
5696    fn write_header<Prev: Pusher>(prev: &mut Prev) {
5697        let mut header = BuiltinNfgenmsg::new();
5698        header.cmd = 11u8;
5699        header.version = 1u8;
5700        prev.as_vec_mut().extend(header.as_slice());
5701    }
5702}
5703impl NetlinkRequest for OpSvcExportGetReqsDump<'_> {
5704    fn protocol(&self) -> Protocol {
5705        Protocol::Generic("nfsd".as_bytes())
5706    }
5707    fn flags(&self) -> u16 {
5708        self.request.flags
5709    }
5710    fn payload(&self) -> &[u8] {
5711        self.request.buf()
5712    }
5713    type ReplyType<'buf> = IterableSvcExportReqs<'buf>;
5714    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5715        Self::decode_request(buf)
5716    }
5717    fn lookup(
5718        buf: &[u8],
5719        offset: usize,
5720        missing_type: Option<u16>,
5721    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5722        Self::decode_request(buf).lookup_attr(offset, missing_type)
5723    }
5724}
5725#[doc = "Respond to one or more svc_export requests\n\nFlags: admin-perm\n\nRequest attributes:\n- [.nested_requests()](PushSvcExportReqs::nested_requests)\n\n"]
5726#[derive(Debug)]
5727pub struct OpSvcExportSetReqsDo<'r> {
5728    request: Request<'r>,
5729}
5730impl<'r> OpSvcExportSetReqsDo<'r> {
5731    pub fn new(mut request: Request<'r>) -> Self {
5732        Self::write_header(request.buf_mut());
5733        Self { request: request }
5734    }
5735    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushSvcExportReqs<&'buf mut Vec<u8>> {
5736        Self::write_header(buf);
5737        PushSvcExportReqs::new(buf)
5738    }
5739    pub fn encode(&mut self) -> PushSvcExportReqs<&mut Vec<u8>> {
5740        PushSvcExportReqs::new(self.request.buf_mut())
5741    }
5742    pub fn into_encoder(self) -> PushSvcExportReqs<RequestBuf<'r>> {
5743        PushSvcExportReqs::new(self.request.buf)
5744    }
5745    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableSvcExportReqs<'a> {
5746        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5747        IterableSvcExportReqs::with_loc(attrs, buf.as_ptr() as usize)
5748    }
5749    fn write_header<Prev: Pusher>(prev: &mut Prev) {
5750        let mut header = BuiltinNfgenmsg::new();
5751        header.cmd = 12u8;
5752        header.version = 1u8;
5753        prev.as_vec_mut().extend(header.as_slice());
5754    }
5755}
5756impl NetlinkRequest for OpSvcExportSetReqsDo<'_> {
5757    fn protocol(&self) -> Protocol {
5758        Protocol::Generic("nfsd".as_bytes())
5759    }
5760    fn flags(&self) -> u16 {
5761        self.request.flags
5762    }
5763    fn payload(&self) -> &[u8] {
5764        self.request.buf()
5765    }
5766    type ReplyType<'buf> = IterableSvcExportReqs<'buf>;
5767    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5768        Self::decode_request(buf)
5769    }
5770    fn lookup(
5771        buf: &[u8],
5772        offset: usize,
5773        missing_type: Option<u16>,
5774    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5775        Self::decode_request(buf).lookup_attr(offset, missing_type)
5776    }
5777}
5778#[doc = "Dump all pending expkey requests\n\nFlags: admin-perm\n\nReply attributes:\n- [.get_requests()](IterableExpkeyReqs::get_requests)\n\n"]
5779#[derive(Debug)]
5780pub struct OpExpkeyGetReqsDump<'r> {
5781    request: Request<'r>,
5782}
5783impl<'r> OpExpkeyGetReqsDump<'r> {
5784    pub fn new(mut request: Request<'r>) -> Self {
5785        Self::write_header(request.buf_mut());
5786        Self {
5787            request: request.set_dump(),
5788        }
5789    }
5790    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushExpkeyReqs<&'buf mut Vec<u8>> {
5791        Self::write_header(buf);
5792        PushExpkeyReqs::new(buf)
5793    }
5794    pub fn encode(&mut self) -> PushExpkeyReqs<&mut Vec<u8>> {
5795        PushExpkeyReqs::new(self.request.buf_mut())
5796    }
5797    pub fn into_encoder(self) -> PushExpkeyReqs<RequestBuf<'r>> {
5798        PushExpkeyReqs::new(self.request.buf)
5799    }
5800    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableExpkeyReqs<'a> {
5801        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5802        IterableExpkeyReqs::with_loc(attrs, buf.as_ptr() as usize)
5803    }
5804    fn write_header<Prev: Pusher>(prev: &mut Prev) {
5805        let mut header = BuiltinNfgenmsg::new();
5806        header.cmd = 13u8;
5807        header.version = 1u8;
5808        prev.as_vec_mut().extend(header.as_slice());
5809    }
5810}
5811impl NetlinkRequest for OpExpkeyGetReqsDump<'_> {
5812    fn protocol(&self) -> Protocol {
5813        Protocol::Generic("nfsd".as_bytes())
5814    }
5815    fn flags(&self) -> u16 {
5816        self.request.flags
5817    }
5818    fn payload(&self) -> &[u8] {
5819        self.request.buf()
5820    }
5821    type ReplyType<'buf> = IterableExpkeyReqs<'buf>;
5822    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5823        Self::decode_request(buf)
5824    }
5825    fn lookup(
5826        buf: &[u8],
5827        offset: usize,
5828        missing_type: Option<u16>,
5829    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5830        Self::decode_request(buf).lookup_attr(offset, missing_type)
5831    }
5832}
5833#[doc = "Respond to one or more expkey requests\n\nFlags: admin-perm\n\nRequest attributes:\n- [.nested_requests()](PushExpkeyReqs::nested_requests)\n\n"]
5834#[derive(Debug)]
5835pub struct OpExpkeySetReqsDo<'r> {
5836    request: Request<'r>,
5837}
5838impl<'r> OpExpkeySetReqsDo<'r> {
5839    pub fn new(mut request: Request<'r>) -> Self {
5840        Self::write_header(request.buf_mut());
5841        Self { request: request }
5842    }
5843    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushExpkeyReqs<&'buf mut Vec<u8>> {
5844        Self::write_header(buf);
5845        PushExpkeyReqs::new(buf)
5846    }
5847    pub fn encode(&mut self) -> PushExpkeyReqs<&mut Vec<u8>> {
5848        PushExpkeyReqs::new(self.request.buf_mut())
5849    }
5850    pub fn into_encoder(self) -> PushExpkeyReqs<RequestBuf<'r>> {
5851        PushExpkeyReqs::new(self.request.buf)
5852    }
5853    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableExpkeyReqs<'a> {
5854        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5855        IterableExpkeyReqs::with_loc(attrs, buf.as_ptr() as usize)
5856    }
5857    fn write_header<Prev: Pusher>(prev: &mut Prev) {
5858        let mut header = BuiltinNfgenmsg::new();
5859        header.cmd = 14u8;
5860        header.version = 1u8;
5861        prev.as_vec_mut().extend(header.as_slice());
5862    }
5863}
5864impl NetlinkRequest for OpExpkeySetReqsDo<'_> {
5865    fn protocol(&self) -> Protocol {
5866        Protocol::Generic("nfsd".as_bytes())
5867    }
5868    fn flags(&self) -> u16 {
5869        self.request.flags
5870    }
5871    fn payload(&self) -> &[u8] {
5872        self.request.buf()
5873    }
5874    type ReplyType<'buf> = IterableExpkeyReqs<'buf>;
5875    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5876        Self::decode_request(buf)
5877    }
5878    fn lookup(
5879        buf: &[u8],
5880        offset: usize,
5881        missing_type: Option<u16>,
5882    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5883        Self::decode_request(buf).lookup_attr(offset, missing_type)
5884    }
5885}
5886#[doc = "Flush nfsd caches (svc_export and/or expkey)\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_mask()](PushCacheFlush::push_mask)\n\n"]
5887#[derive(Debug)]
5888pub struct OpCacheFlushDo<'r> {
5889    request: Request<'r>,
5890}
5891impl<'r> OpCacheFlushDo<'r> {
5892    pub fn new(mut request: Request<'r>) -> Self {
5893        Self::write_header(request.buf_mut());
5894        Self { request: request }
5895    }
5896    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushCacheFlush<&'buf mut Vec<u8>> {
5897        Self::write_header(buf);
5898        PushCacheFlush::new(buf)
5899    }
5900    pub fn encode(&mut self) -> PushCacheFlush<&mut Vec<u8>> {
5901        PushCacheFlush::new(self.request.buf_mut())
5902    }
5903    pub fn into_encoder(self) -> PushCacheFlush<RequestBuf<'r>> {
5904        PushCacheFlush::new(self.request.buf)
5905    }
5906    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableCacheFlush<'a> {
5907        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5908        IterableCacheFlush::with_loc(attrs, buf.as_ptr() as usize)
5909    }
5910    fn write_header<Prev: Pusher>(prev: &mut Prev) {
5911        let mut header = BuiltinNfgenmsg::new();
5912        header.cmd = 15u8;
5913        header.version = 1u8;
5914        prev.as_vec_mut().extend(header.as_slice());
5915    }
5916}
5917impl NetlinkRequest for OpCacheFlushDo<'_> {
5918    fn protocol(&self) -> Protocol {
5919        Protocol::Generic("nfsd".as_bytes())
5920    }
5921    fn flags(&self) -> u16 {
5922        self.request.flags
5923    }
5924    fn payload(&self) -> &[u8] {
5925        self.request.buf()
5926    }
5927    type ReplyType<'buf> = IterableCacheFlush<'buf>;
5928    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5929        Self::decode_request(buf)
5930    }
5931    fn lookup(
5932        buf: &[u8],
5933        offset: usize,
5934        missing_type: Option<u16>,
5935    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5936        Self::decode_request(buf).lookup_attr(offset, missing_type)
5937    }
5938}
5939#[doc = "release NLM locks held by an IP address\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_address()](PushUnlockIp::push_address)\n\n"]
5940#[derive(Debug)]
5941pub struct OpUnlockIpDo<'r> {
5942    request: Request<'r>,
5943}
5944impl<'r> OpUnlockIpDo<'r> {
5945    pub fn new(mut request: Request<'r>) -> Self {
5946        Self::write_header(request.buf_mut());
5947        Self { request: request }
5948    }
5949    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushUnlockIp<&'buf mut Vec<u8>> {
5950        Self::write_header(buf);
5951        PushUnlockIp::new(buf)
5952    }
5953    pub fn encode(&mut self) -> PushUnlockIp<&mut Vec<u8>> {
5954        PushUnlockIp::new(self.request.buf_mut())
5955    }
5956    pub fn into_encoder(self) -> PushUnlockIp<RequestBuf<'r>> {
5957        PushUnlockIp::new(self.request.buf)
5958    }
5959    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableUnlockIp<'a> {
5960        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5961        IterableUnlockIp::with_loc(attrs, buf.as_ptr() as usize)
5962    }
5963    fn write_header<Prev: Pusher>(prev: &mut Prev) {
5964        let mut header = BuiltinNfgenmsg::new();
5965        header.cmd = 16u8;
5966        header.version = 1u8;
5967        prev.as_vec_mut().extend(header.as_slice());
5968    }
5969}
5970impl NetlinkRequest for OpUnlockIpDo<'_> {
5971    fn protocol(&self) -> Protocol {
5972        Protocol::Generic("nfsd".as_bytes())
5973    }
5974    fn flags(&self) -> u16 {
5975        self.request.flags
5976    }
5977    fn payload(&self) -> &[u8] {
5978        self.request.buf()
5979    }
5980    type ReplyType<'buf> = IterableUnlockIp<'buf>;
5981    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5982        Self::decode_request(buf)
5983    }
5984    fn lookup(
5985        buf: &[u8],
5986        offset: usize,
5987        missing_type: Option<u16>,
5988    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5989        Self::decode_request(buf).lookup_attr(offset, missing_type)
5990    }
5991}
5992#[doc = "revoke NFS state under a filesystem path\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_path()](PushUnlockFilesystem::push_path)\n\n"]
5993#[derive(Debug)]
5994pub struct OpUnlockFilesystemDo<'r> {
5995    request: Request<'r>,
5996}
5997impl<'r> OpUnlockFilesystemDo<'r> {
5998    pub fn new(mut request: Request<'r>) -> Self {
5999        Self::write_header(request.buf_mut());
6000        Self { request: request }
6001    }
6002    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushUnlockFilesystem<&'buf mut Vec<u8>> {
6003        Self::write_header(buf);
6004        PushUnlockFilesystem::new(buf)
6005    }
6006    pub fn encode(&mut self) -> PushUnlockFilesystem<&mut Vec<u8>> {
6007        PushUnlockFilesystem::new(self.request.buf_mut())
6008    }
6009    pub fn into_encoder(self) -> PushUnlockFilesystem<RequestBuf<'r>> {
6010        PushUnlockFilesystem::new(self.request.buf)
6011    }
6012    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableUnlockFilesystem<'a> {
6013        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
6014        IterableUnlockFilesystem::with_loc(attrs, buf.as_ptr() as usize)
6015    }
6016    fn write_header<Prev: Pusher>(prev: &mut Prev) {
6017        let mut header = BuiltinNfgenmsg::new();
6018        header.cmd = 17u8;
6019        header.version = 1u8;
6020        prev.as_vec_mut().extend(header.as_slice());
6021    }
6022}
6023impl NetlinkRequest for OpUnlockFilesystemDo<'_> {
6024    fn protocol(&self) -> Protocol {
6025        Protocol::Generic("nfsd".as_bytes())
6026    }
6027    fn flags(&self) -> u16 {
6028        self.request.flags
6029    }
6030    fn payload(&self) -> &[u8] {
6031        self.request.buf()
6032    }
6033    type ReplyType<'buf> = IterableUnlockFilesystem<'buf>;
6034    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
6035        Self::decode_request(buf)
6036    }
6037    fn lookup(
6038        buf: &[u8],
6039        offset: usize,
6040        missing_type: Option<u16>,
6041    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
6042        Self::decode_request(buf).lookup_attr(offset, missing_type)
6043    }
6044}
6045#[doc = "Revoke NFSv4 state acquired through exports of a given path. Unlike\nunlock-filesystem, which operates at superblock granularity, this\ncommand targets only state associated with a specific export path.\nUserspace (exportfs -u) sends this after removing the last client for a\npath so the underlying filesystem can be unmounted.\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_path()](PushUnlockExport::push_path)\n\n"]
6046#[derive(Debug)]
6047pub struct OpUnlockExportDo<'r> {
6048    request: Request<'r>,
6049}
6050impl<'r> OpUnlockExportDo<'r> {
6051    pub fn new(mut request: Request<'r>) -> Self {
6052        Self::write_header(request.buf_mut());
6053        Self { request: request }
6054    }
6055    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushUnlockExport<&'buf mut Vec<u8>> {
6056        Self::write_header(buf);
6057        PushUnlockExport::new(buf)
6058    }
6059    pub fn encode(&mut self) -> PushUnlockExport<&mut Vec<u8>> {
6060        PushUnlockExport::new(self.request.buf_mut())
6061    }
6062    pub fn into_encoder(self) -> PushUnlockExport<RequestBuf<'r>> {
6063        PushUnlockExport::new(self.request.buf)
6064    }
6065    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableUnlockExport<'a> {
6066        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
6067        IterableUnlockExport::with_loc(attrs, buf.as_ptr() as usize)
6068    }
6069    fn write_header<Prev: Pusher>(prev: &mut Prev) {
6070        let mut header = BuiltinNfgenmsg::new();
6071        header.cmd = 18u8;
6072        header.version = 1u8;
6073        prev.as_vec_mut().extend(header.as_slice());
6074    }
6075}
6076impl NetlinkRequest for OpUnlockExportDo<'_> {
6077    fn protocol(&self) -> Protocol {
6078        Protocol::Generic("nfsd".as_bytes())
6079    }
6080    fn flags(&self) -> u16 {
6081        self.request.flags
6082    }
6083    fn payload(&self) -> &[u8] {
6084        self.request.buf()
6085    }
6086    type ReplyType<'buf> = IterableUnlockExport<'buf>;
6087    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
6088        Self::decode_request(buf)
6089    }
6090    fn lookup(
6091        buf: &[u8],
6092        offset: usize,
6093        missing_type: Option<u16>,
6094    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
6095        Self::decode_request(buf).lookup_attr(offset, missing_type)
6096    }
6097}
6098use crate::traits::LookupFn;
6099use crate::utils::RequestBuf;
6100#[derive(Debug)]
6101pub struct Request<'buf> {
6102    buf: RequestBuf<'buf>,
6103    flags: u16,
6104    writeback: Option<&'buf mut Option<RequestInfo>>,
6105}
6106#[allow(unused)]
6107#[derive(Debug, Clone)]
6108pub struct RequestInfo {
6109    protocol: Protocol,
6110    flags: u16,
6111    name: &'static str,
6112    lookup: LookupFn,
6113}
6114impl Request<'static> {
6115    pub fn new() -> Self {
6116        Self::new_from_buf(Vec::new())
6117    }
6118    pub fn new_from_buf(buf: Vec<u8>) -> Self {
6119        Self {
6120            flags: 0,
6121            buf: RequestBuf::Own(buf),
6122            writeback: None,
6123        }
6124    }
6125    pub fn into_buf(self) -> Vec<u8> {
6126        match self.buf {
6127            RequestBuf::Own(buf) => buf,
6128            _ => unreachable!(),
6129        }
6130    }
6131}
6132impl<'buf> Request<'buf> {
6133    pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
6134        buf.clear();
6135        Self::new_extend(buf)
6136    }
6137    pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
6138        Self {
6139            flags: 0,
6140            buf: RequestBuf::Ref(buf),
6141            writeback: None,
6142        }
6143    }
6144    fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
6145        let Some(writeback) = &mut self.writeback else {
6146            return;
6147        };
6148        **writeback = Some(RequestInfo {
6149            protocol,
6150            flags: self.flags,
6151            name,
6152            lookup,
6153        })
6154    }
6155    pub fn buf(&self) -> &Vec<u8> {
6156        self.buf.buf()
6157    }
6158    pub fn buf_mut(&mut self) -> &mut Vec<u8> {
6159        self.buf.buf_mut()
6160    }
6161    #[doc = "Set `NLM_F_CREATE` flag"]
6162    pub fn set_create(mut self) -> Self {
6163        self.flags |= consts::NLM_F_CREATE as u16;
6164        self
6165    }
6166    #[doc = "Set `NLM_F_EXCL` flag"]
6167    pub fn set_excl(mut self) -> Self {
6168        self.flags |= consts::NLM_F_EXCL as u16;
6169        self
6170    }
6171    #[doc = "Set `NLM_F_REPLACE` flag"]
6172    pub fn set_replace(mut self) -> Self {
6173        self.flags |= consts::NLM_F_REPLACE as u16;
6174        self
6175    }
6176    #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
6177    pub fn set_change(self) -> Self {
6178        self.set_create().set_replace()
6179    }
6180    #[doc = "Set `NLM_F_APPEND` flag"]
6181    pub fn set_append(mut self) -> Self {
6182        self.flags |= consts::NLM_F_APPEND as u16;
6183        self
6184    }
6185    #[doc = "Set `self.flags |= flags`"]
6186    pub fn set_flags(mut self, flags: u16) -> Self {
6187        self.flags |= flags;
6188        self
6189    }
6190    #[doc = "Set `self.flags ^= self.flags & flags`"]
6191    pub fn unset_flags(mut self, flags: u16) -> Self {
6192        self.flags ^= self.flags & flags;
6193        self
6194    }
6195    #[doc = "Set `NLM_F_DUMP` flag"]
6196    fn set_dump(mut self) -> Self {
6197        self.flags |= consts::NLM_F_DUMP as u16;
6198        self
6199    }
6200    #[doc = "dump pending nfsd rpc\n\nReply attributes:\n- [.get_xid()](IterableRpcStatus::get_xid)\n- [.get_flags()](IterableRpcStatus::get_flags)\n- [.get_prog()](IterableRpcStatus::get_prog)\n- [.get_version()](IterableRpcStatus::get_version)\n- [.get_proc()](IterableRpcStatus::get_proc)\n- [.get_service_time()](IterableRpcStatus::get_service_time)\n- [.get_saddr4()](IterableRpcStatus::get_saddr4)\n- [.get_daddr4()](IterableRpcStatus::get_daddr4)\n- [.get_saddr6()](IterableRpcStatus::get_saddr6)\n- [.get_daddr6()](IterableRpcStatus::get_daddr6)\n- [.get_sport()](IterableRpcStatus::get_sport)\n- [.get_dport()](IterableRpcStatus::get_dport)\n- [.get_compound_ops()](IterableRpcStatus::get_compound_ops)\n\n"]
6201    pub fn op_rpc_status_get_dump(self) -> OpRpcStatusGetDump<'buf> {
6202        let mut res = OpRpcStatusGetDump::new(self);
6203        res.request.do_writeback(
6204            res.protocol(),
6205            "op-rpc-status-get-dump",
6206            OpRpcStatusGetDump::lookup,
6207        );
6208        res
6209    }
6210    #[doc = "set the maximum number of running threads\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_threads()](PushServer::push_threads)\n- [.push_gracetime()](PushServer::push_gracetime)\n- [.push_leasetime()](PushServer::push_leasetime)\n- [.push_scope()](PushServer::push_scope)\n- [.push_min_threads()](PushServer::push_min_threads)\n- [.push_fh_key()](PushServer::push_fh_key)\n\n"]
6211    pub fn op_threads_set_do(self) -> OpThreadsSetDo<'buf> {
6212        let mut res = OpThreadsSetDo::new(self);
6213        res.request
6214            .do_writeback(res.protocol(), "op-threads-set-do", OpThreadsSetDo::lookup);
6215        res
6216    }
6217    #[doc = "get the maximum number of running threads\n\nReply attributes:\n- [.get_threads()](IterableServer::get_threads)\n- [.get_gracetime()](IterableServer::get_gracetime)\n- [.get_leasetime()](IterableServer::get_leasetime)\n- [.get_scope()](IterableServer::get_scope)\n- [.get_min_threads()](IterableServer::get_min_threads)\n\n"]
6218    pub fn op_threads_get_do(self) -> OpThreadsGetDo<'buf> {
6219        let mut res = OpThreadsGetDo::new(self);
6220        res.request
6221            .do_writeback(res.protocol(), "op-threads-get-do", OpThreadsGetDo::lookup);
6222        res
6223    }
6224    #[doc = "set nfs enabled versions\n\nFlags: admin-perm\n\nRequest attributes:\n- [.nested_version()](PushServerProto::nested_version)\n\n"]
6225    pub fn op_version_set_do(self) -> OpVersionSetDo<'buf> {
6226        let mut res = OpVersionSetDo::new(self);
6227        res.request
6228            .do_writeback(res.protocol(), "op-version-set-do", OpVersionSetDo::lookup);
6229        res
6230    }
6231    #[doc = "get nfs enabled versions\n\nReply attributes:\n- [.get_version()](IterableServerProto::get_version)\n\n"]
6232    pub fn op_version_get_do(self) -> OpVersionGetDo<'buf> {
6233        let mut res = OpVersionGetDo::new(self);
6234        res.request
6235            .do_writeback(res.protocol(), "op-version-get-do", OpVersionGetDo::lookup);
6236        res
6237    }
6238    #[doc = "set nfs running sockets\n\nFlags: admin-perm\n\nRequest attributes:\n- [.nested_addr()](PushServerSock::nested_addr)\n\n"]
6239    pub fn op_listener_set_do(self) -> OpListenerSetDo<'buf> {
6240        let mut res = OpListenerSetDo::new(self);
6241        res.request.do_writeback(
6242            res.protocol(),
6243            "op-listener-set-do",
6244            OpListenerSetDo::lookup,
6245        );
6246        res
6247    }
6248    #[doc = "get nfs running listeners\n\nReply attributes:\n- [.get_addr()](IterableServerSock::get_addr)\n\n"]
6249    pub fn op_listener_get_do(self) -> OpListenerGetDo<'buf> {
6250        let mut res = OpListenerGetDo::new(self);
6251        res.request.do_writeback(
6252            res.protocol(),
6253            "op-listener-get-do",
6254            OpListenerGetDo::lookup,
6255        );
6256        res
6257    }
6258    #[doc = "set the current server pool-mode\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_mode()](PushPoolMode::push_mode)\n\n"]
6259    pub fn op_pool_mode_set_do(self) -> OpPoolModeSetDo<'buf> {
6260        let mut res = OpPoolModeSetDo::new(self);
6261        res.request.do_writeback(
6262            res.protocol(),
6263            "op-pool-mode-set-do",
6264            OpPoolModeSetDo::lookup,
6265        );
6266        res
6267    }
6268    #[doc = "get info about server pool-mode\n\nReply attributes:\n- [.get_mode()](IterablePoolMode::get_mode)\n- [.get_npools()](IterablePoolMode::get_npools)\n\n"]
6269    pub fn op_pool_mode_get_do(self) -> OpPoolModeGetDo<'buf> {
6270        let mut res = OpPoolModeGetDo::new(self);
6271        res.request.do_writeback(
6272            res.protocol(),
6273            "op-pool-mode-get-do",
6274            OpPoolModeGetDo::lookup,
6275        );
6276        res
6277    }
6278    #[doc = "Dump all pending svc_export requests\n\nFlags: admin-perm\n\nReply attributes:\n- [.get_requests()](IterableSvcExportReqs::get_requests)\n\n"]
6279    pub fn op_svc_export_get_reqs_dump(self) -> OpSvcExportGetReqsDump<'buf> {
6280        let mut res = OpSvcExportGetReqsDump::new(self);
6281        res.request.do_writeback(
6282            res.protocol(),
6283            "op-svc-export-get-reqs-dump",
6284            OpSvcExportGetReqsDump::lookup,
6285        );
6286        res
6287    }
6288    #[doc = "Respond to one or more svc_export requests\n\nFlags: admin-perm\n\nRequest attributes:\n- [.nested_requests()](PushSvcExportReqs::nested_requests)\n\n"]
6289    pub fn op_svc_export_set_reqs_do(self) -> OpSvcExportSetReqsDo<'buf> {
6290        let mut res = OpSvcExportSetReqsDo::new(self);
6291        res.request.do_writeback(
6292            res.protocol(),
6293            "op-svc-export-set-reqs-do",
6294            OpSvcExportSetReqsDo::lookup,
6295        );
6296        res
6297    }
6298    #[doc = "Dump all pending expkey requests\n\nFlags: admin-perm\n\nReply attributes:\n- [.get_requests()](IterableExpkeyReqs::get_requests)\n\n"]
6299    pub fn op_expkey_get_reqs_dump(self) -> OpExpkeyGetReqsDump<'buf> {
6300        let mut res = OpExpkeyGetReqsDump::new(self);
6301        res.request.do_writeback(
6302            res.protocol(),
6303            "op-expkey-get-reqs-dump",
6304            OpExpkeyGetReqsDump::lookup,
6305        );
6306        res
6307    }
6308    #[doc = "Respond to one or more expkey requests\n\nFlags: admin-perm\n\nRequest attributes:\n- [.nested_requests()](PushExpkeyReqs::nested_requests)\n\n"]
6309    pub fn op_expkey_set_reqs_do(self) -> OpExpkeySetReqsDo<'buf> {
6310        let mut res = OpExpkeySetReqsDo::new(self);
6311        res.request.do_writeback(
6312            res.protocol(),
6313            "op-expkey-set-reqs-do",
6314            OpExpkeySetReqsDo::lookup,
6315        );
6316        res
6317    }
6318    #[doc = "Flush nfsd caches (svc_export and/or expkey)\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_mask()](PushCacheFlush::push_mask)\n\n"]
6319    pub fn op_cache_flush_do(self) -> OpCacheFlushDo<'buf> {
6320        let mut res = OpCacheFlushDo::new(self);
6321        res.request
6322            .do_writeback(res.protocol(), "op-cache-flush-do", OpCacheFlushDo::lookup);
6323        res
6324    }
6325    #[doc = "release NLM locks held by an IP address\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_address()](PushUnlockIp::push_address)\n\n"]
6326    pub fn op_unlock_ip_do(self) -> OpUnlockIpDo<'buf> {
6327        let mut res = OpUnlockIpDo::new(self);
6328        res.request
6329            .do_writeback(res.protocol(), "op-unlock-ip-do", OpUnlockIpDo::lookup);
6330        res
6331    }
6332    #[doc = "revoke NFS state under a filesystem path\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_path()](PushUnlockFilesystem::push_path)\n\n"]
6333    pub fn op_unlock_filesystem_do(self) -> OpUnlockFilesystemDo<'buf> {
6334        let mut res = OpUnlockFilesystemDo::new(self);
6335        res.request.do_writeback(
6336            res.protocol(),
6337            "op-unlock-filesystem-do",
6338            OpUnlockFilesystemDo::lookup,
6339        );
6340        res
6341    }
6342    #[doc = "Revoke NFSv4 state acquired through exports of a given path. Unlike\nunlock-filesystem, which operates at superblock granularity, this\ncommand targets only state associated with a specific export path.\nUserspace (exportfs -u) sends this after removing the last client for a\npath so the underlying filesystem can be unmounted.\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_path()](PushUnlockExport::push_path)\n\n"]
6343    pub fn op_unlock_export_do(self) -> OpUnlockExportDo<'buf> {
6344        let mut res = OpUnlockExportDo::new(self);
6345        res.request.do_writeback(
6346            res.protocol(),
6347            "op-unlock-export-do",
6348            OpUnlockExportDo::lookup,
6349        );
6350        res
6351    }
6352}
6353#[cfg(test)]
6354mod generated_tests {
6355    use super::*;
6356    #[test]
6357    fn tests() {
6358        let _ = IterableCacheNotify::get_cache_type;
6359        let _ = IterableExpkeyReqs::get_requests;
6360        let _ = IterablePoolMode::get_mode;
6361        let _ = IterablePoolMode::get_npools;
6362        let _ = IterableRpcStatus::get_compound_ops;
6363        let _ = IterableRpcStatus::get_daddr4;
6364        let _ = IterableRpcStatus::get_daddr6;
6365        let _ = IterableRpcStatus::get_dport;
6366        let _ = IterableRpcStatus::get_flags;
6367        let _ = IterableRpcStatus::get_proc;
6368        let _ = IterableRpcStatus::get_prog;
6369        let _ = IterableRpcStatus::get_saddr4;
6370        let _ = IterableRpcStatus::get_saddr6;
6371        let _ = IterableRpcStatus::get_service_time;
6372        let _ = IterableRpcStatus::get_sport;
6373        let _ = IterableRpcStatus::get_version;
6374        let _ = IterableRpcStatus::get_xid;
6375        let _ = IterableServer::get_gracetime;
6376        let _ = IterableServer::get_leasetime;
6377        let _ = IterableServer::get_min_threads;
6378        let _ = IterableServer::get_scope;
6379        let _ = IterableServer::get_threads;
6380        let _ = IterableServerProto::get_version;
6381        let _ = IterableServerSock::get_addr;
6382        let _ = IterableSvcExportReqs::get_requests;
6383        let _ = OpCacheNotifyNotif;
6384        let _ = PushCacheFlush::<&mut Vec<u8>>::push_mask;
6385        let _ = PushExpkeyReqs::<&mut Vec<u8>>::nested_requests;
6386        let _ = PushPoolMode::<&mut Vec<u8>>::push_mode;
6387        let _ = PushServer::<&mut Vec<u8>>::push_fh_key;
6388        let _ = PushServer::<&mut Vec<u8>>::push_gracetime;
6389        let _ = PushServer::<&mut Vec<u8>>::push_leasetime;
6390        let _ = PushServer::<&mut Vec<u8>>::push_min_threads;
6391        let _ = PushServer::<&mut Vec<u8>>::push_scope;
6392        let _ = PushServer::<&mut Vec<u8>>::push_threads;
6393        let _ = PushServerProto::<&mut Vec<u8>>::nested_version;
6394        let _ = PushServerSock::<&mut Vec<u8>>::nested_addr;
6395        let _ = PushSvcExportReqs::<&mut Vec<u8>>::nested_requests;
6396        let _ = PushUnlockExport::<&mut Vec<u8>>::push_path;
6397        let _ = PushUnlockFilesystem::<&mut Vec<u8>>::push_path;
6398        let _ = PushUnlockIp::<&mut Vec<u8>>::push_address;
6399    }
6400}