zsh_module/
options.rs

1use std::{ffi::CStr, os::raw::c_char};
2
3use zsh_sys as zsys;
4
5/// Represents all the options passed to a command.
6pub struct Opts {
7    raw: zsys::Options,
8}
9
10impl Opts {
11    pub(crate) unsafe fn from_raw(raw: zsys::Options) -> Self {
12        Self { raw }
13    }
14    // Taken from `zsh.h`
15    // Let's hope Zsh does not change the implementation of these:
16
17    /// Whether the option was set using a minus.
18    /// E.g:
19    /// ```zsh
20    /// command +o # Returns false
21    /// command -o # Returns true.
22    /// ```
23    pub fn is_minus(&self, c: c_char) -> bool {
24        let expr = unsafe { (*self.raw).ind[c as usize] & 1 };
25        expr != 0
26    }
27    /// Whether the option was set using a plus.
28    /// E.g:
29    /// ```zsh
30    /// command +o # Returns true
31    /// command -o # Returns false
32    /// ```
33    pub fn is_plus(&self, c: c_char) -> bool {
34        let expr = unsafe { (*self.raw).ind[c as usize] & 2 };
35        expr != 0
36    }
37    /// Whether the option was set.
38    /// E.g:
39    /// ```zsh
40    /// command +o # Returns true
41    /// command -o # Returns true
42    /// command # Returns false
43    /// ```
44    pub fn is_set(&self, c: c_char) -> bool {
45        unsafe { (*self.raw).ind[c as usize] != 0 }
46    }
47    /// Returns the argument passed with the option, if any.
48    /// E.g:
49    /// ```zsh
50    /// command +o example # Returns Some("example")
51    /// command -o example2 # Returns Some("example2")
52    /// command -o # Returns None
53    /// command # Returns None
54    /// ```
55    pub fn get_arg(&self, c: c_char) -> Option<&str> {
56        unsafe {
57            let args =
58                std::ptr::slice_from_raw_parts((*self.raw).args, (*self.raw).argscount as usize);
59            let opt = (*self.raw).ind[c as usize];
60            if opt > 3 {
61                CStr::from_ptr((*args)[(opt >> 2) as usize - 1])
62                    .to_str()
63                    .ok()
64            } else {
65                None
66            }
67        }
68    }
69}