# Code usage The first step is to read the static scheme serialization files in order to use them later to read configuration files. All necessary code is available at `shm_rs::static_scheme::init`. There is `SchemeInit` structure which provides initialization functions: - `new_with_path` - creates an instance with specific base file system path. This allows to read `init.shm` file which contains a links to all necessary files which are required to load. - `new` - just creates new instance. Then, the scheme file should be read. - `run_from_file` - reads file from provided relative path. It requires that instance was created using `new_with_path`, otherwise it will throw an error. - `run` - a manual parsing. This function accepts as input parameters an already parsed file by `lexer`. A `lexer` is located at `shm_rs::lexer`. This is a lexering code which performs conversion of text to `nodes`. An initialization of a single file. ```rust let schm = init::SchemeInit::new_with_path("/etc/myproject").unwrap(); let serializators = schm.run_from_file("init_networking.shm", None).unwrap(); ``` An initialization of multiple files. This can be performed either creating a file which includes all necessary files or joining the `serializator` lists. Reading multiple files from init file. ```rust let schm = init::SchemeInit::new_with_path("/etc/myproject").unwrap(); let serializators = schm.run_from_file("init.shm", None).unwrap(); ``` A content of the `init.shm` ```scheme (version 1000) (include "init.s/tags.shm") (include "init.s/actions.shm") (include "init.s/filters.shm") (include "init.s/logdaemon.shm") (include "init.s/logformats.shm") (include "init.s/logsmon.shm") ``` Reading files separatly. ```rust let schm = init::SchemeInit::new_with_path("/etc/myproject").unwrap(); let serializators = schm.run_from_file("init_networking.shm", None).unwrap(); let s1 = schm.run_from_file("init_storage.shm", None).unwrap(); let s2 = schm.run_from_file("init_video.shm", None).unwrap(); serializators.extend(s1); serializators.extend(s2); ``` ## Static Scheme Analysis A static scheme can be analyzed for errors or unwanted situations. ```rust let schm = init::SchemeInit::new_with_path(curdir).unwrap(); let res = schm.run_from_file("examples/analyzer_error/schm_init.shm", None).unwrap(); let scheme = res.get("test_auto").unwrap(); let anres = scheme.analyze().unwrap(); println!("{}", anres); ``` By calling `analyze()` on scheme, the result can be obtained in form of `AnalyzerErrors` which contains messages in a human readable format. ## Translation of the serialized data back to scheme A serialized data from the `dynamic` scheme file can be serialized back into scheme format. For this purpose a functionality was added. ```rust let schm = init::SchemeInit::new_with_path(curdir).unwrap(); let res = schm.run_from_file("logformats.shm", None).unwrap(); let resser = res.get("logformats").unwrap().clone(); let ser_scheme = from_struct(n, resser); ``` See src/scheme_composer. By calling `from_struct` on rust structures and providing statis scheme. The result can be written directly to file. ```rust println!("{}", ser_scheme); ``` ## build.rs A Rust structures/enums can be auto generated by the `build.rs`. ```rust let net_ser = serializators.get("networking").unwrap().clone(); let mut file = OpenOptions::new().create(true).read(true).write(true).truncate(true).open("./src/cfg_raw.rs").unwrap(); let mut rc = RustCode::new(vec![RustCodeDerives::Debug], vec![], None); match net_ser.generate_rust_structs(&mut rc) { Ok(r) => { write!(file, "{}", rc).unwrap(); }, Err(e) => { eprintln!("{}", e); } } ``` Also in `build.rs` a binary or JSON version of preparsed static scheme can be prepared to embed it into binary during compilation. ```rust let schm = init::SchemeInit::new_with_path("/etc/myproject").unwrap(); let serializators = schm.run_from_file("init_networking.shm", None).unwrap(); let s1 = schm.run_from_file("init_storage.shm", None).unwrap(); let s2 = schm.run_from_file("init_video.shm", None).unwrap(); serializators.extend(s1); serializators.extend(s2); // see static_scheme::container let json_str = serializators.serialize_json().unwrap(); // store json_str to file ``` ## Shortcuts In the root of the crate there are a shortcut functions. ```rust let res = shm_rs::static_scheme_init_single(curdir, None); ``` which is equivalent to: ```rust let lex = lexer::Lexer::from_file(curdir).unwrap(); let schm = init::SchemeInit::new().unwrap(); let res = schm.run(&lex, None).unwrap(); ``` ## Hardcode statis scheme in project To avoid distributing an init files and safe time on parsing every time the same data, the static scheme can be parsed once and serialized into binary file which can be hardcoded into project. For this, in `build.rs` use the following steps: ```rust let static_schemes = schm.run_from_file("init.shm", None).unwrap(); let static_schemes_bin = match static_schemes.serialize_bin() { Ok(r) => r, Err(e) => { eprintln!("{}", e); println!("cargo:warning={}", e); panic!("{}", e); } }; let mut file = OpenOptions::new() .create(true) .read(true) .write(true) .truncate(true) .open(curdir) .unwrap(); file.write_all(static_schemes_bin.as_slice()).unwrap(); ``` Then in the project use the following method: ```rust /// An embedding of the static scheme. pub const STATIC_SCHEME_CFG: &'static [u8] = include_bytes!("structures/static_schemes.bin"); pub fn new_local(init_config_dir: Option<&Path>, opt_conf_loc: Option<&Path>, tempstor: E, opt_errcol: Option<&mut Vec<(String, AnalyzerErrors)>>) -> ComResult> { let conf_base_path = opt_conf_loc.map_or(Path::new(CONF_LOCATION_PATH), |v| v); let source = init_config_dir .map_or( ConfigInitSource::PreCompiled(Self::STATIC_SCHEME_CFG), |f| ConfigInitSource::LocalFileSystem(f.to_path_buf()) ); let clfs: Box = Box::new( ConfigLocaFileSystem::new( Some(Self::SCHEME_CFG_VERSION), source, conf_base_path, opt_errcol ) .map_err(|e| map_runtime_error!("{}", e))? ); //let mut tempstor: TempConfig = TempConfig::default(); //let loader: ConfigLoader = let loader: ConfigLoader = ConfigLoader::<()>::new(clfs, tempstor); return Ok(loader); } ```