1use std::path::Path;
5
6use serde::Deserialize;
7
8use crate::path_simplifier::PathSimplifier;
9
10pub(crate) const FILE_INDIRECTION_ARROW: &str = "\n той ";
13
14pub(crate) trait GenericManifest {
15 fn library_path(&self) -> &str;
17
18 fn is_file_format_version_ok(&self) -> bool;
20
21 fn uses_search_path(&self) -> bool {
23 !self.library_path().contains('/') && !self.library_path().contains('\\')
24 }
25
26 fn library_relative_to_manifest(&self) -> bool {
28 let path = self.library_path();
29 !self.uses_search_path()
30 && !path.starts_with('/')
31 && !path.starts_with('\\')
32 && path.chars().nth(1) != Some(':')
33 }
34
35 fn describe_manifest(&self, manifest_path: &Path) -> String {
37 let simplifier = PathSimplifier::new();
38 let manifest_path = simplifier.simplify(manifest_path);
39 let manifest = manifest_path.display();
40 if self.uses_search_path() {
41 format!(
42 "{}{}{} in the dynamic library search path",
43 manifest,
44 FILE_INDIRECTION_ARROW,
45 self.library_path()
46 )
47 } else if self.library_relative_to_manifest() {
48 format!(
49 "{}{}{} relative to the manifest",
50 manifest,
51 FILE_INDIRECTION_ARROW,
52 self.library_path()
53 )
54 } else {
55 let lib_path = Path::new(self.library_path());
56 format!(
57 "{}{}{}",
58 manifest,
59 FILE_INDIRECTION_ARROW,
60 simplifier.simplify(lib_path).display()
61 )
62 }
63 }
64}
65
66pub(crate) mod json_subobjects {
68 use serde::Deserialize;
69
70 #[derive(Debug, Clone, Deserialize, PartialEq, Eq)]
72 pub(crate) struct RuntimeFunctions {
73 #[serde(rename = "xrNegotiateLoaderRuntimeInterface")]
74 pub(crate) xr_negotiate_loader_runtime_interface: Option<String>,
75 }
76
77 #[derive(Debug, Clone, Deserialize, PartialEq, Eq)]
79 pub(crate) struct Runtime {
80 pub(crate) library_path: String,
81 pub(crate) name: Option<String>,
82 pub(crate) functions: Option<RuntimeFunctions>,
83 }
84}
85
86#[derive(Debug, Clone, Deserialize, PartialEq, Eq)]
88pub(crate) struct RuntimeManifest {
89 file_format_version: String,
90 pub(crate) runtime: json_subobjects::Runtime,
91}
92
93impl GenericManifest for RuntimeManifest {
94 fn library_path(&self) -> &str {
95 &self.runtime.library_path
96 }
97 fn is_file_format_version_ok(&self) -> bool {
98 self.file_format_version == "1.0.0"
99 }
100}