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;