Wenpan Rust -- how to package configuration files into binary files

In actual development, various configuration files are often encountered. Usually, various configurations of program operation are read externally to enhance the flexibility of application configuration. Springboot in the java ecosystem provides an example of this design. For springboot applications, the configuration is loaded by default through application.yml. The default application.yml file is entered into the jar package. If you want to change the behavior of the program, you can create an application.yml file in the same directory of the jar package or specify the location of the configuration file through parameters. So is there a way to package the default configuration file into a binary file in the rust ecosystem?
We can achieve this through the [rust-embed](https://github.com/pyrossh/rust-embed) third-party library.
A typical scenario in actual development is: when no configuration file is specified, the default configuration file is used; the configuration file is loaded when the configuration file is included in the same directory of the application.

* Define the location
  of the embedded file and the acquisition function The location and acquisition function of the embedded file are defined in src/resources/embed_resource.rs

  ```rust
  use rust_embed::RustEmbed;

  #[derive(RustEmbed)]
  #[folder = "src/embedfiles/"]
  struct Asset;

  pub fn get_app_default() -> Option<rust_embed::EmbeddedFile> {
    Asset::get("./app_default.yml")
  }
  ```

  The macro defines the directory of embedded files '#[folder = "src/embedfiles/"]', and the get file function takes this directory as the root.

* Use embedded files

  ```rust
  fn main() {
    if Path::new("./app.yml").exists() {
        let contents =
            fs::read_to_string("./app.yml").expect("Read file error!");
        println!("{}", contents);
        return;
    }
    let app = get_app_default().unwrap();
    let f = std::str::from_utf8(app.data.as_ref()).unwrap();
    println!("{}", f);
  }
  ```

According to the priority, we first check whether there is an app.yml file in the same directory of the application, if there is one, load it, otherwise load the default configuration file. The function we defined earlier to get the embedded file returns a struct of rust_embed::EmbeddedFile. Get the file contents by parsing the data member of the struct.

* Test
In order to avoid interference, we put the compiled application mv to the /tmp directory

  ```shell
  cargo build
  mv target/debug/embed /tmp
  ```

Execute embed first, you can see that the output is the content of the default configuration file; create an app.yml file in the same directory of the application, fill in some content, and then execute embed to output the content of the app.yml file.

[Source address](https://github.com/jiashiwen/wenpanrust/tree/main/embed)
The above example has been compiled and executed on macOS, see you in the next issue

Author: Jia Shiwen

{{o.name}}
{{m.name}}

Guess you like

Origin my.oschina.net/u/4090830/blog/5577036