Repository: casey/just
File: src/positional.rs (Rust)

Code before:
pub struct Positional {
  /// Overrides from values of the form `[a-zA-Z_][a-zA-Z0-9_-]*=.*`
  pub overrides: Vec<(String, String)>,
  /// An argument equal to '.', '..', or ending with `/`
  pub search_directory: Option<String>,
  /// Everything else
  pub arguments: Vec<String>,
}

#[derive(Copy, Clone)]
enum ProcessingStep {
  Overrides,
  SearchDir,
  Arguments,
}

impl Positional {
  pub(crate) fn from_values<'values>(
    values: Option<impl IntoIterator<Item = &'values str>>,
  ) -> Result<Self, ConfigError> {
    let mut overrides = Vec::new();
    let mut search_directory = None;
    let mut arguments = Vec::new();

    let mut processing_step = ProcessingStep::Overrides;

    if let Some(values) = values {
      for value in values {
        if let ProcessingStep::Overrides = processing_step {
          if let Some(o) = Self::override_from_value(value) {
            overrides.push(o);
            continue;
          }
          processing_step = ProcessingStep::SearchDir;
        }

        if let ProcessingStep::SearchDir = processing_step {
          if value == "." || value == ".." {
            search_directory = Some(value.to_owned());
            continue;
          } else if let Some(i) = value.rfind('/') {
            let (dir, tail) = value.split_at(i + 1);

            if let Some(ref sdir) = search_directory {
              if sdir != dir {
                return Err(ConfigError::MultipleSearchDir {
                  seen: sdir.clone(),
                  conflicting: dir.to_string(),
                });
              }
            } else {

Review comment (suggestion):
This might be cleaner with something like:

```
let values = values.into_iter().peekable();

while let Some(value) = values.peek() {
  match processing_step {
    // do step, using values.next() to advance iterator
  }
}
```

Not sure though, TIOLI.

Code after:
pub struct Positional {
  /// Overrides from values of the form `[a-zA-Z_][a-zA-Z0-9_-]*=.*`
  pub overrides: Vec<(String, String)>,
  /// An argument equal to '.', '..', or ending with `/`
  pub search_directory: Option<String>,
  /// Everything else
  pub arguments: Vec<String>,
}

#[derive(Copy, Clone)]
enum ProcessingStep {
  Overrides,
  SearchDir,
  Arguments,
}

impl Positional {
  pub(crate) fn from_values<'values>(
    values: Option<impl IntoIterator<Item = &'values str>>,
  ) -> Result<Self, ConfigError> {
    let mut overrides = Vec::new();
    let mut search_directory = None;
    let mut arguments = Vec::new();

    let mut processing_step = ProcessingStep::Overrides;

    if let Some(values) = values {
      let mut values = values.into_iter().peekable();
      while let Some(value) = values.peek() {
        let value = *value;
        match processing_step {
          ProcessingStep::Overrides => {
            if let Some(o) = Self::override_from_value(value) {
              overrides.push(o);
              values.next();
            } else {
              processing_step = ProcessingStep::SearchDir;
            }
          }
          ProcessingStep::SearchDir => {
            if value == "." || value == ".." {
              search_directory = Some(value.to_owned());
              values.next();
            } else if let Some(i) = value.rfind('/') {
              let (dir, tail) = value.split_at(i + 1);

              if let Some(ref seen) = search_directory {
                if seen != dir {
                  return Err(ConfigError::ConflictingSearchDirArgs {
                    seen: seen.clone(),
                    conflicting: dir.into(),