3个版本 (破坏性更新)

0.3.0 2022年3月16日
0.2.0 2021年7月8日
0.1.0 2021年5月7日

配置 中排名 308

Download history 764/week @ 2024-03-17 742/week @ 2024-03-24 957/week @ 2024-03-31 844/week @ 2024-04-07 825/week @ 2024-04-14 974/week @ 2024-04-21 843/week @ 2024-04-28 1570/week @ 2024-05-05 831/week @ 2024-05-12 944/week @ 2024-05-19 1073/week @ 2024-05-26 916/week @ 2024-06-02 1023/week @ 2024-06-09 673/week @ 2024-06-16 749/week @ 2024-06-23 424/week @ 2024-06-30

每月下载量 2,906
33 crate 使用(直接使用5个)

MIT 协议

19KB
151

env-file-reader

Build Status Codecov Latest Version Docs License: MIT

用于在Rust中从环境文件中读取环境变量的库。

用法

假设这是位于 examples/.env 的环境文件的 内容

CLIENT_ID=YOUR_CLIENT_ID
CLIENT_SECRET=YOUR_CLIENT_SECRET

现在你想读取此文件并将环境变量暴露给你的Rust应用程序。你可以通过使用 env-file-reader crate轻松完成此操作

use env_file_reader::read_file;

fn main() -> std::io::Result<()> {
  let env_variables = read_file("examples/.env")?;
  
  assert_eq!(&env_variables["CLIENT_ID"], "YOUR_CLIENT_ID");
  assert_eq!(&env_variables["CLIENT_SECRET"], "YOUR_CLIENT_SECRET");

  Ok(())
}

env-file-reader crate公开了 read_file 函数,你可以向该函数传递环境文件的路径。然后,read_file 函数解析环境文件并提取包含的变量,将它们作为 HashMap<String, String> 返回,然后你的Rust应用程序可以轻松地访问它们。

变量名和Unicode支持

变量和值支持UTF-8。拥有如下所示的环境文件是完全可以的

🦄=💖
💖=🦄
use env_file_reader::read_file;

fn main() -> std::io::Result<()> {
  let env_variables = read_file("examples/.env.utf8")?;
  
  assert_eq!(&env_variables["🦄"], "💖");
  assert_eq!(&env_variables["💖"], "🦄");

  Ok(())
}

变量(和未引号的值)支持除空白字符以外的每个字符,包括引号(`、'、"),# 和 =,所以尽情使用吧

use env_file_reader::read_str;

fn main() -> std::io::Result<()> {
  let env_variables = read_str(
    r"123-_variable\$*-@🦄=sprinkely-sprinkely-💖s-and_🐱s@the🏟️",
  )?;
  
  assert_eq!(
    &env_variables[r"123-_variable\$*-@🦄"],
    "sprinkely-sprinkely-💖s-and_🐱s@the🏟️",
  );

  Ok(())
}

可选的export关键字

env-file-reader 支持类似 bash 的环境文件,其中变量通过 export 命令导出到环境变量中

export CLIENT_ID=YOUR_EXPORTED_CLIENT_ID
export CLIENT_SECRET=YOUR_EXPORTED_CLIENT_SECRET
use env_file_reader::read_file;

fn main() -> std::io::Result<()> {
  let env_variables = read_file("examples/.env.exported")?;
  
  assert_eq!(&env_variables["CLIENT_ID"], "YOUR_EXPORTED_CLIENT_ID");
  assert_eq!(
    &env_variables["CLIENT_SECRET"], "YOUR_EXPORTED_CLIENT_SECRET",
  );

  Ok(())
}

读取多个环境文件

有时你的环境被分成多个文件(例如,一个包含你想要存储在Kubernetes secret中的秘密的环境文件,另一个包含你想要存储在Kubernetes config map中的非秘密环境文件)。env-file-reader 支持通过 read_files 函数将多个环境文件读取到一个 HashMap 中,其中包含所有变量

use env_file_reader::read_files;

fn main() -> std::io::Result<()> {
  let env_variables = read_files(&[
    "examples/.env",
    "examples/.env.utf8",
  ])?;
  
  assert_eq!(&env_variables["CLIENT_ID"], "YOUR_CLIENT_ID");
  assert_eq!(&env_variables["CLIENT_SECRET"], "YOUR_CLIENT_SECRET");
  assert_eq!(&env_variables["🦄"], "💖");
  assert_eq!(&env_variables["💖"], "🦄");

  Ok(())
}

环境文件将按照提供给 read_files 的顺序连续读取。因此,较后定义的变量将覆盖先前的变量

use env_file_reader::read_files;

fn main() -> std::io::Result<()> {
  let env_variables = read_files(&[
    "examples/.env",
    "examples/.env.exported",
  ])?;
  
  assert_eq!(&env_variables["CLIENT_ID"], "YOUR_EXPORTED_CLIENT_ID");
  assert_eq!(
    &env_variables["CLIENT_SECRET"], "YOUR_EXPORTED_CLIENT_SECRET",
  );

  Ok(())
}

从字符串读取环境变量

除了 read_fileread_files 之外,env-file-reader 还提供了从字符串中直接读取环境变量的选项。

use env_file_reader::read_str;

const ENV_FILE: &str = "
  CLIENT_ID=YOUR_CLIENT_ID
  CLIENT_SECRET=YOUR_CLIENT_SECRET
";

fn main() -> std::io::Result<()> {
  let env_variables = read_str(ENV_FILE)?;
  
  assert_eq!(&env_variables["CLIENT_ID"], "YOUR_CLIENT_ID");
  assert_eq!(&env_variables["CLIENT_SECRET"], "YOUR_CLIENT_SECRET");

  Ok(())
}

注释和空行

环境文件可以包含以 # 开头的单行注释和空行。想象一下,这是一个位于 examples/.env.comments 的环境文件。

# A comment
CLIENT_ID=YOUR_CLIENT_ID # A comment at the end of the line

# Empty lines are fine, too

# Another comment
CLIENT_SECRET=YOUR_CLIENT_SECRET # Another comment behind a value

env-file-reader 可以解析这个文件,忽略空行和注释。

use env_file_reader::read_file;

fn main() -> std::io::Result<()> {
  let env_variables = read_file("examples/.env.comments")?;
  
  assert_eq!(&env_variables["CLIENT_ID"], "YOUR_CLIENT_ID");
  assert_eq!(&env_variables["CLIENT_SECRET"], "YOUR_CLIENT_SECRET");

  Ok(())
}

引号和多行值

如果您需要一个更强大的值,例如包含空格、引号、等号等(参见关于 Unicode 支持的部分),您可以将它们用引号括起来。支持的引号是双引号(")、单引号(')和反引号(`)。用双引号括起来的字符串可以包含单引号、反引号等。它们还支持转义引号,因此 "a string with \"double quotes\"" 将有效。

1="I support whitespaces and = and # and even this: \""
2='single quotes work, too and they can contain "double quotes"'
3=`backticks are "also" valid 'quotes'`
use env_file_reader::read_file;

fn main() -> std::io::Result<()> {
  let env_variables = read_file("examples/.env.quotes")?;
  
  assert_eq!(
    &env_variables["1"], 
    "I support whitespaces and = and # and even this: \"",
  );
  assert_eq!(
    &env_variables["2"], 
    "single quotes work, too and they can contain \"double quotes\"",
  );
  assert_eq!(
    &env_variables["3"], 
    "backticks are \"also\" valid 'quotes'",
  );

  Ok(())
}

多行字符串也受支持,如下所示,可以是字面行断行,也可以是显式类型的 \n

PRIVATE_KEY1="-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----"

# PRIVATE_KEY2 is identical to PRIVATE_KEY1
PRIVATE_KEY2="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
use env_file_reader::read_file;

fn main() -> std::io::Result<()> {
  let env_variables = read_file("examples/.env.multiline")?;
  
  assert_eq!(
    &env_variables["PRIVATE_KEY1"], 
    "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
  );
  assert_eq!(
    &env_variables["PRIVATE_KEY2"], 
    "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
  );

  Ok(())
}

关于转义字符的说明: 引号字符串只支持显式类型的新行和转义的引号本身。不支持其他显式类型特殊字符,如 \t\r。因此,值 "hello\n\t\"world\"" 在通过 env-file-reader 处理时将具有以下值。

hello
\t"world"

不是

hello
    "world"

如果您需要支持其他显式类型特殊字符,请提交一个 issue。

空白符

在等号周围的空白是允许的。同样,变量名之前和值之后的空白也是允许的。它们在解析过程中会被修剪。

use env_file_reader::read_str;

const ENV_FILE: &str = "
      CLIENT_ID =     YOUR_CLIENT_ID
  CLIENT_SECRET =YOUR_CLIENT_SECRET
";

fn main() -> std::io::Result<()> {
  let env_variables = read_str(ENV_FILE)?;
  
  assert_eq!(&env_variables["CLIENT_ID"], "YOUR_CLIENT_ID");
  assert_eq!(&env_variables["CLIENT_SECRET"], "YOUR_CLIENT_SECRET");

  Ok(())
}

如果您需要在值中保留前导或尾随空白,请考虑将其用引号括起来。

use env_file_reader::read_str;

const ENV_FILE: &str = "
      CLIENT_ID = '    YOUR_CLIENT_ID    '
  CLIENT_SECRET =YOUR_CLIENT_SECRET
";

fn main() -> std::io::Result<()> {
  let env_variables = read_str(ENV_FILE)?;
  
  assert_eq!(&env_variables["CLIENT_ID"], "    YOUR_CLIENT_ID    ");
  assert_eq!(&env_variables["CLIENT_SECRET"], "YOUR_CLIENT_SECRET");

  Ok(())
}

空值

您的变量可以是空的。

CLIENT_ID=
CLIENT_SECRET=
use env_file_reader::read_file;

fn main() -> std::io::Result<()> {
  let env_variables = read_file("examples/.env.empty")?;
  
  assert_eq!(&env_variables["CLIENT_ID"], "");
  assert_eq!(&env_variables["CLIENT_SECRET"], "");

  Ok(())
}

错误

如果解析环境文件失败,将返回 std::io::Error。错误包括所有正常的 io 错误,如缺失文件。

use env_file_reader::read_file;

let err = read_file(".env.which.does.not.exist")
  .err()
  .unwrap();
    
assert_eq!(err.kind(), std::io::ErrorKind::NotFound);

此外,解析可能会因格式错误的环境文件而失败。如果是这种情况,将返回自定义错误,ParseError

use env_file_reader::read_str;

let err = read_str("badly formatted env file")
  .err()
  .unwrap();

assert_eq!(err.kind(), std::io::ErrorKind::InvalidInput);
assert_eq!(err.to_string(), "ParseError");

依赖

~1.5–3.5MB
~26K SLoC