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}