1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use std::collections::HashSet;
use std::fs::File;
use std::io::prelude::*;
use std::path::{Path, PathBuf};
use log::info;
use flowcore::model::lib_manifest::DEFAULT_LIB_RUST_MANIFEST_FILENAME;
use flowcore::model::function_definition::FunctionDefinition;
use flowcore::model::lib_manifest::LibraryManifest;
use crate::errors::*;
const GET_MANIFEST_HEADER: &str = "
/// Return the LibraryManifest for this library
pub fn get_manifest() -> Result<LibraryManifest> {
let metadata = MetaData {
name: env!(\"CARGO_PKG_NAME\").into(),
version: env!(\"CARGO_PKG_VERSION\").into(),
description: env!(\"CARGO_PKG_DESCRIPTION\").into(),
authors: env!(\"CARGO_PKG_AUTHORS\")
.split(':')
.map(|s| s.to_string())
.collect(),
};
let lib_url = Url::parse(&format!(\"lib://{}\", metadata.name))?;
let mut manifest = LibraryManifest::new(lib_url, metadata);\n
";
#[allow(clippy::unnecessary_wraps)]
pub fn write(lib_root: &Path, lib_manifest: &LibraryManifest, filename: &Path) -> Result<()> {
let mut manifest_file = File::create(&filename)?;
let mut modules = HashSet::<&str>::new();
for module_url in lib_manifest.locators.keys() {
let module_name = module_url
.path_segments()
.chain_err(|| "Could not get path segments")?
.into_iter()
.next()
.chain_err(|| "Could not get first path segment")?;
modules.insert(module_name);
}
for module in modules {
manifest_file.write_all(format!("\n/// functions from module '{}'", module).as_bytes())?;
manifest_file.write_all(
format!("\n#[path=\"{}/{}/mod.rs\"]", lib_root.display(), module).as_bytes(),
)?;
manifest_file.write_all(format!("\npub mod {};\n", module).as_bytes())?;
}
manifest_file.write_all(GET_MANIFEST_HEADER.as_bytes())?;
for reference in lib_manifest.locators.keys() {
let parts: Vec<&str> = reference
.path_segments()
.chain_err(|| "Could not get Location segments")?
.collect::<Vec<&str>>();
let implementation_struct = format!(
"{}::{}",
parts[0..parts.len() - 1].join("::"),
FunctionDefinition::camel_case(parts[2])
);
let manifest_entry = format!(
" manifest.locators.insert(
Url::parse(\"{}\")?,
Native(Arc::new({})),
);\n\n",
reference, implementation_struct
);
manifest_file.write_all(manifest_entry.as_bytes())?;
}
manifest_file.write_all(" Ok(manifest)\n}".as_bytes())?;
info!(
"Generated library Rust manifest at '{}'",
filename.display()
);
Ok(())
}
pub fn manifest_filename(base_dir: &Path) -> PathBuf {
let mut filename = base_dir.to_path_buf();
filename.push(DEFAULT_LIB_RUST_MANIFEST_FILENAME);
filename
}