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

Code before:
      .exists()
      .to_string(),
  )
}

fn quote(_context: &FunctionContext, s: &str) -> Result<String, String> {
  Ok(format!("'{}'", s.replace('\'', "'\\''")))
}

fn replace(_context: &FunctionContext, s: &str, from: &str, to: &str) -> Result<String, String> {
  Ok(s.replace(from, to))
}

fn sha256(_context: &FunctionContext, s: &str) -> Result<String, String> {
  use sha2::{Digest, Sha256};
  let mut hasher = Sha256::new();
  hasher.update(s);
  let hash = hasher.finalize();
  Ok(format!("{:x}", hash))
}

fn sha256_file(_context: &FunctionContext, path: &str) -> Result<String, String> {
  use sha2::{Digest, Sha256};
  let mut hasher = Sha256::new();
  let mut file = std::fs::File::open(path).unwrap();
  std::io::copy(&mut file, &mut hasher).unwrap();
  let hash = hasher.finalize();
  Ok(format!("{:x}", hash))
}

fn trim(_context: &FunctionContext, s: &str) -> Result<String, String> {
  Ok(s.trim().to_owned())
}

fn trim_end(_context: &FunctionContext, s: &str) -> Result<String, String> {
  Ok(s.trim_end().to_owned())
}

fn trim_end_match(_context: &FunctionContext, s: &str, pat: &str) -> Result<String, String> {
  Ok(s.strip_suffix(pat).unwrap_or(s).to_owned())
}

fn trim_end_matches(_context: &FunctionContext, s: &str, pat: &str) -> Result<String, String> {
  Ok(s.trim_end_matches(pat).to_owned())
}

fn trim_start(_context: &FunctionContext, s: &str) -> Result<String, String> {
  Ok(s.trim_start().to_owned())
}

fn trim_start_match(_context: &FunctionContext, s: &str, pat: &str) -> Result<String, String> {

Review comment (bug):
These unwraps should both be handled. Something like:

```suggestion
  let mut file = std::fs::File::open(path).map_err(|err| format!("Failed to open file at `{}`: {}", path, err))?;
  std::io::copy(&mut file, &mut hasher).map_err(|err| format!("Failed to read file at `{}`: {}", path, err)?;
```

Code after:
      .exists()
      .to_string(),
  )
}

fn quote(_context: &FunctionContext, s: &str) -> Result<String, String> {
  Ok(format!("'{}'", s.replace('\'', "'\\''")))
}

fn replace(_context: &FunctionContext, s: &str, from: &str, to: &str) -> Result<String, String> {
  Ok(s.replace(from, to))
}

fn sha256(_context: &FunctionContext, s: &str) -> Result<String, String> {
  use sha2::{Digest, Sha256};
  let mut hasher = Sha256::new();
  hasher.update(s);
  let hash = hasher.finalize();
  Ok(format!("{:x}", hash))
}

fn sha256_file(context: &FunctionContext, path: &str) -> Result<String, String> {
  use sha2::{Digest, Sha256};
  let justpath = context.search.working_directory.join(path);
  let mut hasher = Sha256::new();
  let mut file = std::fs::File::open(&justpath)
    .map_err(|err| format!("Failed to open file at `{:?}`: {}", &justpath.to_str(), err))?;
  std::io::copy(&mut file, &mut hasher)
    .map_err(|err| format!("Failed to read file at `{:?}`: {}", &justpath.to_str(), err))?;
  let hash = hasher.finalize();
  Ok(format!("{:x}", hash))
}

fn trim(_context: &FunctionContext, s: &str) -> Result<String, String> {
  Ok(s.trim().to_owned())
}

fn trim_end(_context: &FunctionContext, s: &str) -> Result<String, String> {
  Ok(s.trim_end().to_owned())
}

fn trim_end_match(_context: &FunctionContext, s: &str, pat: &str) -> Result<String, String> {
  Ok(s.strip_suffix(pat).unwrap_or(s).to_owned())
}

fn trim_end_matches(_context: &FunctionContext, s: &str, pat: &str) -> Result<String, String> {
  Ok(s.trim_end_matches(pat).to_owned())
}

fn trim_start(_context: &FunctionContext, s: &str) -> Result<String, String> {
  Ok(s.trim_start().to_owned())