Repository: tauri-apps/tauri
File: crates/tauri-cli/src/lib.rs (Rust)

Code before:
  type Err = anyhow::Error;

  fn from_str(config: &str) -> std::result::Result<Self, Self::Err> {
    if config.starts_with('{') {
      Ok(Self(
        serde_json::from_str(config).context("invalid configuration JSON")?,
      ))
    } else {
      let path = PathBuf::from(config);
      if path.exists() {
        let raw = &read_to_string(&path)
            .with_context(|| format!("invalid configuration at file {config}"))?;
        if let Some(extension) = path.extension() {
          match extension.to_str().expect("invalid unicode in file extension") {
            "toml" => Ok(Self(::toml::from_str(raw)?)),
            "json" | "json5" => Ok(Self(serde_json::from_str(raw)?)),
            _ => anyhow::bail!("unsupported file type")
          }
        } else {
          anyhow::bail!("invalid file path (requires file extension)")
        }
      } else {
        anyhow::bail!("provided configuration path does not exist")
      }
    }
  }
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
pub enum RunMode {
  Desktop,
  #[cfg(target_os = "macos")]
  Ios,
  Android,
}

impl Display for RunMode {
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    write!(
      f,
      "{}",
      match self {
        Self::Desktop => "desktop",
        #[cfg(target_os = "macos")]
        Self::Ios => "iOS",
        Self::Android => "android",
      }
    )
  }
}


Review comment (suggestion):
we can always default to JSON, and for Json5, we need to use `json5` crate
```suggestion
        match path.extension() {
          Some(ext) if ext == "toml" => Ok(Self(::toml::from_str(raw)?)),
          Some(ext) if ext == "json5" => Ok(Self(json5::from_str(raw)?)),
          // default to JSON
          _ => Ok(Self(serde_json::from_str(raw)?))
        }
```

Code after:
  type Err = anyhow::Error;

  fn from_str(config: &str) -> std::result::Result<Self, Self::Err> {
    if config.starts_with('{') {
      Ok(Self(
        serde_json::from_str(config).context("invalid configuration JSON")?,
      ))
    } else {
      let path = PathBuf::from(config);
      if path.exists() {
        let raw = &read_to_string(&path)
          .with_context(|| format!("invalid configuration at file {config}"))?;
        match path.extension() {
          Some(ext) if ext == "toml" => Ok(Self(::toml::from_str(raw)?)),
          Some(ext) if ext == "json5" => Ok(Self(::json5::from_str(raw)?)),
          // treat all other extensions as json
          _ => Ok(Self(
            // from tauri-utils/src/config/parse.rs:
            // we also want to support **valid** json5 in the .json extension
            // if the json5 is not valid the serde_json error for regular json will be returned.
            match ::json5::from_str(raw) {
              Ok(json5) => json5,
              Err(_) => serde_json::from_str(raw)?,
            },
          )),
        }
      } else {
        anyhow::bail!("provided configuration path does not exist")
      }
    }
  }
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
pub enum RunMode {
  Desktop,
  #[cfg(target_os = "macos")]
  Ios,
  Android,
}

impl Display for RunMode {
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    write!(
      f,
      "{}",
      match self {
        Self::Desktop => "desktop",
        #[cfg(target_os = "macos")]
        Self::Ios => "iOS",
        Self::Android => "android",