diff options
author | Thomas Otto <th1000s@posteo.net> | 2021-11-27 17:04:47 +0100 |
---|---|---|
committer | Dan Davison <dandavison7@gmail.com> | 2021-11-29 08:39:56 -0500 |
commit | b34a0311222ccd9b864e733606a0088a501089fc (patch) | |
tree | 32f5623929364e74aef43f6694a496cf81981d08 | |
parent | 14272816193484bdf1c1228c2c23fcc16d5c9d69 (diff) |
Clean up FakeParentArgs
Can fake once, for_scope, or with a given list.
-rw-r--r-- | src/handlers/grep.rs | 570 | ||||
-rw-r--r-- | src/utils/process.rs | 276 |
2 files changed, 460 insertions, 386 deletions
diff --git a/src/handlers/grep.rs b/src/handlers/grep.rs index cffb98ef..25f4b8a1 100644 --- a/src/handlers/grep.rs +++ b/src/handlers/grep.rs @@ -406,7 +406,7 @@ pub fn _parse_grep_line<'b>(regex: &Regex, line: &'b str) -> Option<GrepLine<'b> None } }) - .unwrap(); // The regex matches so one of the three alternatrives must have matched + .unwrap(); // The regex matches so one of the three alternatives must have matched let code = caps.get(8).unwrap().as_str().into(); Some(GrepLine { @@ -421,83 +421,73 @@ pub fn _parse_grep_line<'b>(regex: &Regex, line: &'b str) -> Option<GrepLine<'b> #[cfg(test)] mod tests { use crate::handlers::grep::{parse_grep_line, GrepLine, LineType}; - use crate::utils::process::tests::cfg; + use crate::utils::process::tests::FakeParentArgs; #[test] fn test_parse_grep_match() { let fake_parent_grep_command = "git --doesnt-matter grep --nor-this nor_this -- nor_this"; - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - assert_eq!( - parse_grep_line("src/co-7-fig.rs:xxx"), - Some(GrepLine { - path: "src/co-7-fig.rs".into(), - line_number: None, - line_type: LineType::Match, - code: "xxx".into(), - submatches: None, - }) - ); - } - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - assert_eq!( - parse_grep_line("src/config.rs:use crate::minusplus::MinusPlus;"), - Some(GrepLine { - path: "src/config.rs".into(), - line_number: None, - line_type: LineType::Match, - code: "use crate::minusplus::MinusPlus;".into(), - submatches: None, - }) - ); - } - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - assert_eq!( - parse_grep_line( - "src/config.rs: pub line_numbers_style_minusplus: MinusPlus<Style>," - ), - Some(GrepLine { - path: "src/config.rs".into(), - line_number: None, - line_type: LineType::Match, - code: " pub line_numbers_style_minusplus: MinusPlus<Style>,".into(), - submatches: None, - }) - ); - } - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - assert_eq!( - parse_grep_line("src/con-fig.rs:use crate::minusplus::MinusPlus;"), - Some(GrepLine { - path: "src/con-fig.rs".into(), - line_number: None, - line_type: LineType::Match, - code: "use crate::minusplus::MinusPlus;".into(), - submatches: None, - }) - ); - } - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - assert_eq!( - parse_grep_line( - "src/con-fig.rs: pub line_numbers_style_minusplus: MinusPlus<Style>," - ), - Some(GrepLine { - path: "src/con-fig.rs".into(), - line_number: None, - line_type: LineType::Match, - code: " pub line_numbers_style_minusplus: MinusPlus<Style>,".into(), - submatches: None, - }) - ); - } - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - assert_eq!( + let _args = FakeParentArgs::for_scope(&fake_parent_grep_command); + + assert_eq!( + parse_grep_line("src/co-7-fig.rs:xxx"), + Some(GrepLine { + path: "src/co-7-fig.rs".into(), + line_number: None, + line_type: LineType::Match, + code: "xxx".into(), + submatches: None, + }) + ); + + assert_eq!( + parse_grep_line("src/config.rs:use crate::minusplus::MinusPlus;"), + Some(GrepLine { + path: "src/config.rs".into(), + line_number: None, + line_type: LineType::Match, + code: "use crate::minusplus::MinusPlus;".into(), + submatches: None, + }) + ); + + assert_eq!( + parse_grep_line( + "src/config.rs: pub line_numbers_style_minusplus: MinusPlus<Style>," + ), + Some(GrepLine { + path: "src/config.rs".into(), + line_number: None, + line_type: LineType::Match, + code: " pub line_numbers_style_minusplus: MinusPlus<Style>,".into(), + submatches: None, + }) + ); + + assert_eq!( + parse_grep_line("src/con-fig.rs:use crate::minusplus::MinusPlus;"), + Some(GrepLine { + path: "src/con-fig.rs".into(), + line_number: None, + line_type: LineType::Match, + code: "use crate::minusplus::MinusPlus;".into(), + submatches: None, + }) + ); + + assert_eq!( + parse_grep_line( + "src/con-fig.rs: pub line_numbers_style_minusplus: MinusPlus<Style>," + ), + Some(GrepLine { + path: "src/con-fig.rs".into(), + line_number: None, + line_type: LineType::Match, + code: " pub line_numbers_style_minusplus: MinusPlus<Style>,".into(), + submatches: None, + }) + ); + + assert_eq!( parse_grep_line( "src/de lta.rs:pub fn delta<I>(lines: ByteLines<I>, writer: &mut dyn Write, config: &Config) -> std::io::Result<()>" ), @@ -509,10 +499,8 @@ mod tests { submatches: None, }) ); - } - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - assert_eq!( + + assert_eq!( parse_grep_line( "src/de lta.rs: pub fn new(writer: &'a mut dyn Write, config: &'a Config) -> Self {" ), @@ -524,82 +512,72 @@ mod tests { submatches: None, }) ); - } } #[test] fn test_parse_grep_n_match() { let fake_parent_grep_command = "/usr/local/bin/git --doesnt-matter grep --nor-this nor_this -- nor_this"; - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - assert_eq!( - parse_grep_line("src/co-7-fig.rs:7:xxx"), - Some(GrepLine { - path: "src/co-7-fig.rs".into(), - line_number: Some(7), - line_type: LineType::Match, - code: "xxx".into(), - submatches: None, - }) - ); - } - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - assert_eq!( - parse_grep_line("src/config.rs:21:use crate::minusplus::MinusPlus;"), - Some(GrepLine { - path: "src/config.rs".into(), - line_number: Some(21), - line_type: LineType::Match, - code: "use crate::minusplus::MinusPlus;".into(), - submatches: None, - }) - ); - } - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - assert_eq!( - parse_grep_line( - "src/config.rs:95: pub line_numbers_style_minusplus: MinusPlus<Style>," - ), - Some(GrepLine { - path: "src/config.rs".into(), - line_number: Some(95), - line_type: LineType::Match, - code: " pub line_numbers_style_minusplus: MinusPlus<Style>,".into(), - submatches: None, - }) - ); - } - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - assert_eq!( - parse_grep_line("Makefile:10:test: unit-test end-to-end-test"), - Some(GrepLine { - path: "Makefile".into(), - line_number: Some(10), - line_type: LineType::Match, - code: "test: unit-test end-to-end-test".into(), - submatches: None, - }) - ); - } - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - assert_eq!( - parse_grep_line( - "Makefile:16: ./tests/test_raw_output_matches_git_on_full_repo_history" - ), - Some(GrepLine { - path: "Makefile".into(), - line_number: Some(16), - line_type: LineType::Match, - code: " ./tests/test_raw_output_matches_git_on_full_repo_history".into(), - submatches: None, - }) - ); - } + let _args = FakeParentArgs::for_scope(&fake_parent_grep_command); + + assert_eq!( + parse_grep_line("src/co-7-fig.rs:7:xxx"), + Some(GrepLine { + path: "src/co-7-fig.rs".into(), + line_number: Some(7), + line_type: LineType::Match, + code: "xxx".into(), + submatches: None, + }) + ); + + assert_eq!( + parse_grep_line("src/config.rs:21:use crate::minusplus::MinusPlus;"), + Some(GrepLine { + path: "src/config.rs".into(), + line_number: Some(21), + line_type: LineType::Match, + code: "use crate::minusplus::MinusPlus;".into(), + submatches: None, + }) + ); + + assert_eq!( + parse_grep_line( + "src/config.rs:95: pub line_numbers_style_minusplus: MinusPlus<Style>," + ), + Some(GrepLine { + path: "src/config.rs".into(), + line_number: Some(95), + line_type: LineType::Match, + code: " pub line_numbers_style_minusplus: MinusPlus<Style>,".into(), + submatches: None, + }) + ); + + assert_eq!( + parse_grep_line("Makefile:10:test: unit-test end-to-end-test"), + Some(GrepLine { + path: "Makefile".into(), + line_number: Some(10), + line_type: LineType::Match, + code: "test: unit-test end-to-end-test".into(), + submatches: None, + }) + ); + + assert_eq!( + parse_grep_line( + "Makefile:16: ./tests/test_raw_output_matches_git_on_full_repo_history" + ), + Some(GrepLine { + path: "Makefile".into(), + line_number: Some(16), + line_type: LineType::Match, + code: " ./tests/test_raw_output_matches_git_on_full_repo_history".into(), + submatches: None, + }) + ); } #[test] @@ -609,77 +587,69 @@ mod tests { // This fails: we can't parse it currently. let fake_parent_grep_command = "/usr/local/bin/git --doesnt-matter grep --nor-this nor_this -- nor_this"; - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - assert_eq!( - parse_grep_line("etc/examples/119-within-line-edits:4:repo=$(mktemp -d)"), - Some(GrepLine { - path: "etc/examples/119-within-line-edits".into(), - line_number: Some(4), - line_type: LineType::Match, - code: "repo=$(mktemp -d)".into(), - submatches: None, - }) - ); - } + let _args = FakeParentArgs::once(&fake_parent_grep_command); + + assert_eq!( + parse_grep_line("etc/examples/119-within-line-edits:4:repo=$(mktemp -d)"), + Some(GrepLine { + path: "etc/examples/119-within-line-edits".into(), + line_number: Some(4), + line_type: LineType::Match, + code: "repo=$(mktemp -d)".into(), + submatches: None, + }) + ); } #[test] fn test_parse_grep_no_match() { let fake_parent_grep_command = "/usr/local/bin/git --doesnt-matter grep --nor-this nor_this -- nor_this"; - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - assert_eq!( - parse_grep_line("src/co-7-fig.rs-xxx"), - Some(GrepLine { - path: "src/co-7-fig.rs".into(), - line_number: None, - line_type: LineType::Context, - code: "xxx".into(), - submatches: None, - }) - ); - } - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - assert_eq!( - parse_grep_line("src/config.rs- pub available_terminal_width: usize,"), - Some(GrepLine { - path: "src/config.rs".into(), - line_number: None, - line_type: LineType::Context, - code: " pub available_terminal_width: usize,".into(), - submatches: None, - }) - ); - } - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - assert_eq!( - parse_grep_line("src/con-fig.rs-use crate::minusplus::MinusPlus;"), - Some(GrepLine { - path: "src/con-fig.rs".into(), - line_number: None, - line_type: LineType::Context, - code: "use crate::minusplus::MinusPlus;".into(), - submatches: None, - }) - ); - } - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - assert_eq!( - parse_grep_line("de-lta.rs- if self.source == Source::Unknown {"), - Some(GrepLine { - path: "de-lta.rs".into(), - line_number: None, - line_type: LineType::Context, - code: " if self.source == Source::Unknown {".into(), - submatches: None, - }) - ); - } + let _args = FakeParentArgs::for_scope(&fake_parent_grep_command); + + assert_eq!( + parse_grep_line("src/co-7-fig.rs-xxx"), + Some(GrepLine { + path: "src/co-7-fig.rs".into(), + line_number: None, + line_type: LineType::Context, + code: "xxx".into(), + submatches: None, + }) + ); + + assert_eq!( + parse_grep_line("src/config.rs- pub available_terminal_width: usize,"), + Some(GrepLine { + path: "src/config.rs".into(), + line_number: None, + line_type: LineType::Context, + code: " pub available_terminal_width: usize,".into(), + submatches: None, + }) + ); + + assert_eq!( + parse_grep_line("src/con-fig.rs-use crate::minusplus::MinusPlus;"), + Some(GrepLine { + path: "src/con-fig.rs".into(), + line_number: None, + line_type: LineType::Context, + code: "use crate::minusplus::MinusPlus;".into(), + submatches: None, + }) + ); + + assert_eq!( + parse_grep_line("de-lta.rs- if self.source == Source::Unknown {"), + Some(GrepLine { + path: "de-lta.rs".into(), + line_number: None, + line_type: LineType::Context, + code: " if self.source == Source::Unknown {".into(), + submatches: None, + }) + ); } #[test] @@ -687,51 +657,47 @@ mod tests { // git grep -n let fake_parent_grep_command = "/usr/local/bin/git --doesnt-matter grep --nor-this nor_this -- nor_this"; - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - assert_eq!( - parse_grep_line("src/co-7-fig.rs-7-xxx"), - Some(GrepLine { - path: "src/co-7-fig.rs".into(), - line_number: Some(7), - line_type: LineType::Context, - code: "xxx".into(), - submatches: None, - }) - ); - } - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - assert_eq!( - parse_grep_line("src/config.rs-58- pub available_terminal_width: usize,"), - Some(GrepLine { - path: "src/config.rs".into(), - line_number: Some(58), - line_type: LineType::Context, - code: " pub available_terminal_width: usize,".into(), - submatches: None, - }) - ); - } + + let _args = FakeParentArgs::for_scope(&fake_parent_grep_command); + assert_eq!( + parse_grep_line("src/co-7-fig.rs-7-xxx"), + Some(GrepLine { + path: "src/co-7-fig.rs".into(), + line_number: Some(7), + line_type: LineType::Context, + code: "xxx".into(), + submatches: None, + }) + ); + + assert_eq!( + parse_grep_line("src/config.rs-58- pub available_terminal_width: usize,"), + Some(GrepLine { + path: "src/config.rs".into(), + line_number: Some(58), + line_type: LineType::Context, + code: " pub available_terminal_width: usize,".into(), + submatches: None, + }) + ); } #[test] fn test_parse_grep_match_no_extension() { let fake_parent_grep_command = "/usr/local/bin/git --doesnt-matter grep --nor-this nor_this -- nor_this"; - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - assert_eq!( - parse_grep_line("Makefile:xxx"), - Some(GrepLine { - path: "Makefile".into(), - line_number: None, - line_type: LineType::Match, - code: "xxx".into(), - submatches: None, - }) - ); - } + let _args = FakeParentArgs::once(&fake_parent_grep_command); + + assert_eq!( + parse_grep_line("Makefile:xxx"), + Some(GrepLine { + path: "Makefile".into(), + line_number: None, + line_type: LineType::Match, + code: "xxx".into(), + submatches: None, + }) + ); } #[test] @@ -739,19 +705,17 @@ mod tests { // git grep -n let fake_parent_grep_command = "/usr/local/bin/git --doesnt-matter grep --nor-this nor_this -- nor_this"; - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - assert_eq!( - parse_grep_line("Makefile:7:xxx"), - Some(GrepLine { - path: "Makefile".into(), - line_number: Some(7), - line_type: LineType::Match, - code: "xxx".into(), - submatches: None, - }) - ); - } + let _args = FakeParentArgs::once(&fake_parent_grep_command); + assert_eq!( + parse_grep_line("Makefile:7:xxx"), + Some(GrepLine { + path: "Makefile".into(), + line_number: Some(7), + line_type: LineType::Match, + code: "xxx".into(), + submatches: None, + }) + ); } #[test] @@ -760,19 +724,18 @@ mod tests { // git grep -W let fake_parent_grep_command = "/usr/local/bin/git --doesnt-matter grep --nor-this nor_this -- nor_this"; - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - assert_eq!( - parse_grep_line("src/config.rs=pub struct Config {"), // match - Some(GrepLine { - path: "src/config.rs".into(), - line_number: None, - line_type: LineType::ContextHeader, - code: "pub struct Config {".into(), - submatches: None, - }) - ); - } + + let _args = FakeParentArgs::once(&fake_parent_grep_command); + assert_eq!( + parse_grep_line("src/config.rs=pub struct Config {"), // match + Some(GrepLine { + path: "src/config.rs".into(), + line_number: None, + line_type: LineType::ContextHeader, + code: "pub struct Config {".into(), + submatches: None, + }) + ); } #[test] @@ -781,49 +744,44 @@ mod tests { // git grep -n -W let fake_parent_grep_command = "/usr/local/bin/git --doesnt-matter grep --nor-this nor_this -- nor_this"; - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - assert_eq!( - parse_grep_line("src/config.rs=57=pub struct Config {"), - Some(GrepLine { - path: "src/config.rs".into(), - line_number: Some(57), - line_type: LineType::ContextHeader, - code: "pub struct Config {".into(), - submatches: None, - }) - ); - } + let _args = FakeParentArgs::once(&fake_parent_grep_command); + + assert_eq!( + parse_grep_line("src/config.rs=57=pub struct Config {"), + Some(GrepLine { + path: "src/config.rs".into(), + line_number: Some(57), + line_type: LineType::ContextHeader, + code: "pub struct Config {".into(), + submatches: None, + }) + ); } #[test] fn test_parse_grep_not_grep_output() { let fake_parent_grep_command = "/usr/local/bin/git --doesnt-matter grep --nor-this nor_this -- nor_this"; - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - let not_grep_output = "| expose it in delta's color output styled with grep:"; - assert_eq!(parse_grep_line(not_grep_output), None); - } + let _args = FakeParentArgs::once(&fake_parent_grep_command); + + let not_grep_output = "| expose it in delta's color output styled with grep:"; + assert_eq!(parse_grep_line(not_grep_output), None); } #[test] fn test_parse_grep_parent_command_is_not_grep_1() { let fake_parent_grep_command = "/usr/local/bin/notgrep --doesnt-matter --nor-this nor_this -- nor_this"; - { - let _args = cfg::WithArgs::new(&fake_parent_grep_command); - let apparently_grep_output = "src/co-7-fig.rs:xxx"; - assert_eq!(parse_grep_line(apparently_grep_output), None); - } + let _args = FakeParentArgs::once(&fake_parent_grep_command); + + let apparently_grep_output = "src/co-7-fig.rs:xxx"; + assert_eq!(parse_grep_line(apparently_grep_output), None); } #[test] fn test_parse_grep_parent_command_is_not_grep_2() { - { - // No fake parent grep command - let apparently_grep_output = "src/co-7-fig.rs:xxx"; - assert_eq!(parse_grep_line(apparently_grep_output), None); - } + // No fake parent grep command + let apparently_grep_output = "src/co-7-fig.rs:xxx"; + assert_eq!(parse_grep_line(apparently_grep_output), None); } } diff --git a/src/utils/process.rs b/src/utils/process.rs index 124defa7..ef59d318 100644 --- a/src/utils/process.rs +++ b/src/utils/process.rs @@ -46,31 +46,27 @@ pub enum ProcessArgs<T> { } pub fn git_blame_filename_extension() -> Option<String> { - calling_process_cmdline(ProcInfo::new(), blame::guess_git_blame_filename_extension) + calling_process_cmdline(ProcInfo::new(), guess_git_blame_filename_extension) } -mod blame { - use super::*; - - pub fn guess_git_blame_filename_extension(args: &[String]) -> ProcessArgs<String> { - let all_args = args.iter().map(|s| s.as_str()); +pub fn guess_git_blame_filename_extension(args: &[String]) -> ProcessArgs<String> { + let all_args = args.iter().map(|s| s.as_str()); - // See git(1) and git-blame(1). Some arguments separate their parameter with space or '=', e.g. - // --date 2015 or --date=2015. - let git_blame_options_with_parameter = - "-C -c -L --since --ignore-rev --ignore-revs-file --contents --reverse --date"; + // See git(1) and git-blame(1). Some arguments separate their parameter with space or '=', e.g. + // --date 2015 or --date=2015. + let git_blame_options_with_parameter = + "-C -c -L --since --ignore-rev --ignore-revs-file --contents --reverse --date"; - let selected_args = - skip_uninteresting_args(all_args, git_blame_options_with_parameter.split(' ')); + let selected_args = + skip_uninteresting_args(all_args, git_blame_options_with_parameter.split(' ')); - match selected_args.as_slice() { - [_git, "blame", .., last_arg] => match last_arg.split('.').last() { - Some(arg) => ProcessArgs::Args(arg.to_string()), - None => ProcessArgs::ArgError, - }, - [_git, "blame"] => ProcessArgs::ArgError, - _ => ProcessArgs::OtherProcess, - } + match selected_args.as_slice() { + [_git, "blame", .., last_arg] => match last_arg.split('.').last() { + Some(arg) => ProcessArgs::Args(arg.to_string()), + None => ProcessArgs::ArgError, + }, + [_git, "blame"] => ProcessArgs::ArgError, + _ => ProcessArgs::OtherProcess, } } @@ -339,13 +335,14 @@ where { #[cfg(test)] { - if let Some(args) = tests::cfg::WithArgs::get() { + if let Some(args) = tests::FakeParentArgs::get() { match extract_args(&args) { ProcessArgs::Args(result) => return Some(result), _ => return None, } } } + let my_pid = info.my_pid(); // 1) Try the parent process. If delta is set as the pager in git, then git is the parent process. @@ -409,6 +406,10 @@ where P: ProcessInterface, F: FnMut(Pid, usize), { + // Probably bad input, not a tree: + if distance > 2000 { + return; + } if let Some(proc) = info.process(pid) { if let Some(pid) = proc.parent() { f(pid, distance); @@ -421,58 +422,105 @@ where #[cfg(test)] pub mod tests { - use super::blame::*; use super::*; use itertools::Itertools; - - pub mod cfg { - use std::cell::RefCell; - - #[derive(Debug, PartialEq)] - enum TlsState<T> { - Some(T), - None, - Invalid, + use std::cell::RefCell; + use std::rc::Rc; + + thread_local! { + static FAKE_ARGS: RefCell<TlsState<Vec<String>>> = RefCell::new(TlsState::None); + } + + #[derive(Debug, PartialEq)] + enum TlsState<T> { + Once(T), + Scope(T), + With(usize, Rc<Vec<T>>), + None, + Invalid, + } + + // When calling `FakeParentArgs::get()`, it can return `Some(values)` which were set earlier + // during in the #[test]. Otherwise returns None. + // This value can be valid once: `FakeParentArgs::once(val)`, for the entire scope: + // `FakeParentArgs::for_scope(val)`, or can be different values everytime `get()` is called: + // `FakeParentArgs::with([val1, val2, val3])`. + // It is an error if `once` or `with` values remain unused, or are overused. + // Note: The values are stored per-thread, so the expectation is that no thread boundaries are + // crossed. + pub struct FakeParentArgs {} + impl FakeParentArgs { + pub fn once(args: &str) -> Self { + Self::new(args, |v| TlsState::Once(v), "once") } - - thread_local! { - static FAKE_ARGS: RefCell<TlsState<Vec<String>>> = RefCell::new(TlsState::None); + pub fn for_scope(args: &str) -> Self { + Self::new(args, |v| TlsState::Scope(v), "for_scope") } - - pub struct WithArgs {} - impl WithArgs { - pub fn new(args: &str) -> Self { - let string_vec = args.split(' ').map(str::to_owned).collect(); - assert!( - FAKE_ARGS.with(|a| a.replace(TlsState::Some(string_vec))) != TlsState::Invalid, - "test logic error (in new): wrong WithArgs scope?" - ); - WithArgs {} - } - pub fn get() -> Option<Vec<String>> { - FAKE_ARGS.with(|a| { - let old_value = a.replace_with(|old_value| match old_value { - TlsState::Some(_) => TlsState::Invalid, - TlsState::None => TlsState::None, - TlsState::Invalid => TlsState::Invalid, - }); - - match old_value { - TlsState::Some(args) => Some(args), - TlsState::None => None, - TlsState::Invalid => { - panic!("test logic error (in get): wrong WithArgs scope?") - } - } - }) + fn new<F>(args: &str, initial: F, from_: &str) -> Self + where + F: Fn(Vec<String>) -> TlsState<Vec<String>>, + { + let string_vec = args.split(' ').map(str::to_owned).collect(); + if FAKE_ARGS.with(|a| a.replace(initial(string_vec))) != TlsState::None { + Self::error(from_); } + FakeParentArgs {} } - impl Drop for WithArgs { - fn drop(&mut self) { - // clears an invalid state - FAKE_ARGS.with(|a| a.replace(TlsState::None)); + pub fn with(args: &[&str]) -> Self { + let with = TlsState::With( + 0, + Rc::new( + args.iter() + .map(|a| a.split(' ').map(str::to_owned).collect()) + .collect(), + ), + |