Skip to main content

laminar_connectors/fpml/profile/
bundled.rs

1//! Profile files shipped in the binary.
2
3/// Bundled profiles: `(name, root file)`.
4pub const BUNDLED_PROFILES: &[(&str, &str)] = &[
5    (
6        "fpml-5-13-confirmation-trade",
7        "fpml-5-13/confirmation/trade.toml",
8    ),
9    (
10        "fpml-5-13-confirmation-rates",
11        "fpml-5-13/confirmation/trade-rates.toml",
12    ),
13    (
14        "fpml-5-13-confirmation-fx",
15        "fpml-5-13/confirmation/trade-fx.toml",
16    ),
17    (
18        "fpml-5-13-confirmation-commodity",
19        "fpml-5-13/confirmation/trade-commodity.toml",
20    ),
21    (
22        "fpml-5-13-confirmation-credit",
23        "fpml-5-13/confirmation/trade-credit.toml",
24    ),
25    (
26        "fpml-5-13-confirmation-equity-options",
27        "fpml-5-13/confirmation/trade-equity-options.toml",
28    ),
29    (
30        "fpml-5-13-confirmation-equity-swaps",
31        "fpml-5-13/confirmation/trade-equity-swaps.toml",
32    ),
33    (
34        "fpml-5-13-confirmation-equity-volatility",
35        "fpml-5-13/confirmation/trade-equity-volatility.toml",
36    ),
37    (
38        "fpml-5-13-confirmation-securities",
39        "fpml-5-13/confirmation/trade-securities.toml",
40    ),
41    (
42        "fpml-5-13-confirmation-cross-asset",
43        "fpml-5-13/confirmation/trade-cross-asset.toml",
44    ),
45    (
46        "fpml-5-13-confirmation-document",
47        "fpml-5-13/confirmation/document.toml",
48    ),
49    (
50        "fpml-5-13-confirmation-loan-servicing",
51        "fpml-5-13/confirmation/loan-servicing.toml",
52    ),
53    (
54        "fpml-5-13-confirmation-loan-trading",
55        "fpml-5-13/confirmation/loan-trading.toml",
56    ),
57    (
58        "fpml-5-13-confirmation-loan-facilities",
59        "fpml-5-13/confirmation/loan-facilities.toml",
60    ),
61];
62
63macro_rules! profile_files {
64    ($($path:literal),* $(,)?) => {
65        &[$(($path, include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fpml/profiles/", $path)))),*]
66    };
67}
68
69/// Every bundled profile file, by path relative to `fpml/profiles/`.
70const FILES: &[(&str, &str)] = profile_files!(
71    "fpml-5-13/confirmation/assets.toml",
72    "fpml-5-13/confirmation/common.toml",
73    "fpml-5-13/confirmation/document.toml",
74    "fpml-5-13/confirmation/loan-columns.toml",
75    "fpml-5-13/confirmation/loan-facilities.toml",
76    "fpml-5-13/confirmation/loan-servicing.toml",
77    "fpml-5-13/confirmation/loan-trading.toml",
78    "fpml-5-13/confirmation/loans.toml",
79    "fpml-5-13/confirmation/messages.toml",
80    "fpml-5-13/confirmation/options.toml",
81    "fpml-5-13/confirmation/products/commodity.toml",
82    "fpml-5-13/confirmation/products/credit.toml",
83    "fpml-5-13/confirmation/products/cross-asset.toml",
84    "fpml-5-13/confirmation/products/equity.toml",
85    "fpml-5-13/confirmation/products/fx.toml",
86    "fpml-5-13/confirmation/products/rates.toml",
87    "fpml-5-13/confirmation/products/securities.toml",
88    "fpml-5-13/confirmation/trade-columns.toml",
89    "fpml-5-13/confirmation/trade-commodity.toml",
90    "fpml-5-13/confirmation/trade-credit.toml",
91    "fpml-5-13/confirmation/trade-cross-asset.toml",
92    "fpml-5-13/confirmation/trade-equity-options.toml",
93    "fpml-5-13/confirmation/trade-equity-swaps.toml",
94    "fpml-5-13/confirmation/trade-equity-volatility.toml",
95    "fpml-5-13/confirmation/trade-fx.toml",
96    "fpml-5-13/confirmation/trade-rates.toml",
97    "fpml-5-13/confirmation/trade-securities.toml",
98    "fpml-5-13/confirmation/trade.toml",
99);
100
101pub(super) fn root(name: &str) -> Option<&'static str> {
102    BUNDLED_PROFILES
103        .iter()
104        .find(|(bundled, _)| *bundled == name)
105        .map(|(_, path)| *path)
106}
107
108pub(super) fn file(path: &str) -> Option<&'static str> {
109    FILES
110        .iter()
111        .find(|(bundled, _)| *bundled == path)
112        .map(|(_, content)| *content)
113}
114
115/// Resolve `include` relative to the bundled file `from`, without leaving the bundle.
116pub(super) fn join(from: &str, include: &str) -> Result<String, String> {
117    let mut parts: Vec<&str> = from.split('/').collect();
118    parts.pop();
119    for part in include.split('/') {
120        match part {
121            "" | "." => {}
122            ".." => {
123                parts
124                    .pop()
125                    .ok_or_else(|| format!("include '{include}' leaves the bundled profiles"))?;
126            }
127            part => parts.push(part),
128        }
129    }
130    Ok(parts.join("/"))
131}
132
133#[cfg(test)]
134mod tests {
135    use super::*;
136
137    /// Every profile file shipped in the source tree is embedded, and nothing else.
138    #[test]
139    fn every_profile_file_is_bundled() {
140        let root = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("fpml/profiles");
141        let mut on_disk = Vec::new();
142        let mut pending = vec![root.clone()];
143        while let Some(directory) = pending.pop() {
144            for entry in std::fs::read_dir(directory).unwrap() {
145                let path = entry.unwrap().path();
146                if path.is_dir() {
147                    pending.push(path);
148                } else if path
149                    .extension()
150                    .is_some_and(|extension| extension == "toml")
151                {
152                    let relative = path.strip_prefix(&root).unwrap();
153                    on_disk.push(relative.to_string_lossy().replace('\\', "/"));
154                }
155            }
156        }
157        on_disk.sort();
158        let mut bundled: Vec<String> = FILES.iter().map(|(path, _)| (*path).to_owned()).collect();
159        bundled.sort();
160        assert_eq!(on_disk, bundled);
161        for (_, root) in BUNDLED_PROFILES {
162            assert!(file(root).is_some(), "{root}");
163        }
164    }
165}