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
103
104
105
106
107
108
109
110
111
112
113
114
115
use log::trace;
use std::path::PathBuf;
use crate::file::MrbFile;
use crate::fs::RUBY_LOAD_PATH;
use crate::{Mrb, MrbError};
pub trait MrbLoadSources {
fn def_file<T>(
&self,
filename: T,
require: fn(Self) -> Result<(), MrbError>,
) -> Result<(), MrbError>
where
T: AsRef<str>;
fn def_file_for_type<T, F>(&self, filename: T) -> Result<(), MrbError>
where
T: AsRef<str>,
F: MrbFile;
fn def_rb_source_file<T, F>(&self, filename: T, contents: F) -> Result<(), MrbError>
where
T: AsRef<str>,
F: AsRef<[u8]>;
fn normalize_source_path<T>(&self, filename: T) -> PathBuf
where
T: AsRef<str>,
{
let mut path = PathBuf::from(filename.as_ref());
if path.is_relative() {
path = PathBuf::from(RUBY_LOAD_PATH).join(filename.as_ref());
}
path
}
}
impl MrbLoadSources for Mrb {
fn def_file<T>(
&self,
filename: T,
require: fn(Self) -> Result<(), MrbError>,
) -> Result<(), MrbError>
where
T: AsRef<str>,
{
let api = self.borrow();
let path = self.normalize_source_path(filename.as_ref());
if let Some(parent) = path.parent() {
api.vfs.create_dir_all(parent)?;
}
if !api.vfs.is_file(&path) {
let contents = format!("# virtual source file -- {:?}", &path);
api.vfs.write_file(&path, contents)?;
}
let mut metadata = api.vfs.metadata(&path).unwrap_or_default();
metadata.require = Some(require);
api.vfs.set_metadata(&path, metadata)?;
trace!(
"Added rust-backed ruby source file with require func -- {:?}",
&path
);
Ok(())
}
fn def_file_for_type<T, F>(&self, filename: T) -> Result<(), MrbError>
where
T: AsRef<str>,
F: MrbFile,
{
self.def_file(filename.as_ref(), F::require)
}
fn def_rb_source_file<T, F>(&self, filename: T, contents: F) -> Result<(), MrbError>
where
T: AsRef<str>,
F: AsRef<[u8]>,
{
let api = self.borrow();
let path = self.normalize_source_path(filename.as_ref());
if let Some(parent) = path.parent() {
api.vfs.create_dir_all(parent)?;
}
api.vfs.write_file(&path, contents.as_ref())?;
let metadata = api.vfs.metadata(&path).unwrap_or_default();
api.vfs.set_metadata(&path, metadata)?;
trace!("Added pure ruby source file -- {:?}", &path);
Ok(())
}
}