Skip to main content

git_policy_cli/
rule_argument_rewrite.rs

1//! What:
2//!  The shared result and builder of fixed transforms that add tokens to a command line.
3//! Why:
4//!  A transform either leaves the caller's arguments alone or returns a new owned list;
5//!      saying which lets the caller keep the original vector without comparing contents.
6//!
7//! In TS you'd write (pseudocode):
8//! ```ts
9//! // type ArgumentRewrite = { kind: 'unchanged' } | { kind: 'rewritten'; args: string[] };
10//! ```
11
12/// `OsString` is owned operating-system text of raw bytes (sibling `String` must be UTF-8).
13use std::ffi::OsString;
14
15/// What:
16///  The outcome of one transform.
17///  An `enum` is a closed set of named alternatives;
18///       `Rewritten` carries the new owned argument list,
19///  `Vec<OsString>`.
20/// Why:
21///   The TypeScript rules returned the same array object to mean "unchanged";
22///  Rust
23///       says it with a variant instead of object identity.
24///
25/// In TS you'd write (pseudocode):
26/// ```ts
27/// type ArgumentRewrite = { kind: 'unchanged' } | { kind: 'rewritten'; args: string[] };
28/// ```
29#[derive(Clone, Debug, Eq, PartialEq)]
30pub enum ArgumentRewrite {
31    /// Forward the caller's arguments as they are.
32    Unchanged,
33    /// Forward this list instead.
34    Rewritten(Vec<OsString>),
35}
36
37/// What:
38///  Copy `arguments` with `inserted` placed before index `at`.
39///  `&[&str]` borrows a
40///       list of text spellings;
41///  `usize` is the list index type.
42/// Why:
43///   Injected tokens are ASCII flags,
44///  while every existing argument keeps its bytes.
45///
46/// In TS you'd write (pseudocode):
47/// ```ts
48/// const result = [...args.slice(0, at), ...inserted, ...args.slice(at)];
49/// ```
50pub fn insert_tokens(arguments: &[OsString], at: usize, inserted: &[&str]) -> Vec<OsString> {
51    // `with_capacity` reserves room for the known final length.
52    let mut result: Vec<OsString> =
53        Vec::<OsString>::with_capacity(arguments.len() + inserted.len());
54    let mut index: usize = 0;
55    while index < arguments.len() {
56        if index == at {
57            // `for token in inserted` borrows each spelling; `OsString::from` copies it.
58            for token in inserted {
59                result.push(OsString::from(token));
60            }
61        }
62        // `.clone()` copies the argument bytes into the owned result.
63        result.push(arguments[index].clone());
64        index += 1;
65    }
66    if at >= arguments.len() {
67        for token in inserted {
68            result.push(OsString::from(token));
69        }
70    }
71    return result;
72}
73
74/// Insertion at the start,
75///  middle and end.
76#[cfg(test)]
77#[path = "rule_argument_rewrite_tests.rs"]
78mod tests;