rquickjs_extra_os/
lib.rs

1// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// Copyright Emile Fugulin for modifications.
3// SPDX-License-Identifier: Apache-2.0
4use std::env;
5
6use rquickjs::{
7    Ctx, Exception, Result,
8    module::{Declarations, Exports, ModuleDef},
9    prelude::Func,
10};
11use rquickjs_extra_utils::{
12    module::export_default,
13    sysinfo::{get_arch, get_platform},
14};
15
16#[cfg(unix)]
17use self::unix::{EOL, get_release, get_type, get_version};
18#[cfg(windows)]
19use self::windows::{EOL, get_release, get_type, get_version};
20
21#[cfg(unix)]
22mod unix;
23#[cfg(windows)]
24mod windows;
25
26fn get_home_dir(ctx: Ctx<'_>) -> Result<String> {
27    home::home_dir()
28        .map(|val| val.to_string_lossy().into_owned())
29        .ok_or_else(|| Exception::throw_message(&ctx, "Could not determine home directory"))
30}
31
32fn get_tmp_dir() -> String {
33    env::temp_dir().to_string_lossy().to_string()
34}
35
36fn get_available_parallelism() -> usize {
37    num_cpus::get()
38}
39
40pub struct OsModule;
41
42impl ModuleDef for OsModule {
43    fn declare(declare: &Declarations) -> Result<()> {
44        declare.declare("arch")?;
45        declare.declare("availableParallelism")?;
46        declare.declare("EOL")?;
47        declare.declare("platform")?;
48        declare.declare("homedir")?;
49        declare.declare("release")?;
50        declare.declare("tmpdir")?;
51        declare.declare("type")?;
52        declare.declare("version")?;
53
54        declare.declare("default")?;
55
56        Ok(())
57    }
58
59    fn evaluate<'js>(ctx: &Ctx<'js>, exports: &Exports<'js>) -> Result<()> {
60        export_default(ctx, exports, |default| {
61            default.set("arch", Func::from(get_arch))?;
62            default.set(
63                "availableParallelism",
64                Func::from(get_available_parallelism),
65            )?;
66            default.set("EOL", EOL)?;
67            default.set("homedir", Func::from(get_home_dir))?;
68            default.set("platform", Func::from(get_platform))?;
69            default.set("release", Func::from(get_release))?;
70            default.set("tmpdir", Func::from(get_tmp_dir))?;
71            default.set("type", Func::from(get_type))?;
72            default.set("version", Func::from(get_version))?;
73
74            Ok(())
75        })
76    }
77}
78
79#[cfg(test)]
80mod tests {
81    use rquickjs_extra_test::{ModuleEvaluator, call_test, test_async_with};
82
83    use super::*;
84
85    #[tokio::test]
86    async fn test_type() {
87        test_async_with(|ctx| {
88            Box::pin(async move {
89                ModuleEvaluator::eval_rust::<OsModule>(ctx.clone(), "os")
90                    .await
91                    .unwrap();
92
93                let module = ModuleEvaluator::eval_js(
94                    ctx.clone(),
95                    "test",
96                    r#"
97                        import { type } from 'os';
98
99                        export async function test() {
100                            return type()
101                        }
102                    "#,
103                )
104                .await
105                .unwrap();
106
107                let result = call_test::<String, _>(&ctx, &module, ()).await;
108
109                assert!(result == "Linux" || result == "Windows_NT" || result == "Darwin");
110            })
111        })
112        .await;
113    }
114
115    #[tokio::test]
116    async fn test_release() {
117        test_async_with(|ctx| {
118            Box::pin(async move {
119                ModuleEvaluator::eval_rust::<OsModule>(ctx.clone(), "os")
120                    .await
121                    .unwrap();
122
123                let module = ModuleEvaluator::eval_js(
124                    ctx.clone(),
125                    "test",
126                    r#"
127                        import { release } from 'os';
128
129                        export async function test() {
130                            return release()
131                        }
132                    "#,
133                )
134                .await
135                .unwrap();
136
137                let result = call_test::<String, _>(&ctx, &module, ()).await;
138
139                assert!(!result.is_empty()); // Format is platform dependant
140            })
141        })
142        .await;
143    }
144
145    #[tokio::test]
146    async fn test_version() {
147        test_async_with(|ctx| {
148            Box::pin(async move {
149                ModuleEvaluator::eval_rust::<OsModule>(ctx.clone(), "os")
150                    .await
151                    .unwrap();
152
153                let module = ModuleEvaluator::eval_js(
154                    ctx.clone(),
155                    "test",
156                    r#"
157                        import { version } from 'os';
158
159                        export async function test() {
160                            return version()
161                        }
162                    "#,
163                )
164                .await
165                .unwrap();
166
167                let result = call_test::<String, _>(&ctx, &module, ()).await;
168
169                assert!(!result.is_empty()); // Format is platform dependant
170            })
171        })
172        .await;
173    }
174
175    #[tokio::test]
176    async fn test_available_parallelism() {
177        test_async_with(|ctx| {
178            Box::pin(async move {
179                ModuleEvaluator::eval_rust::<OsModule>(ctx.clone(), "os")
180                    .await
181                    .unwrap();
182
183                let module = ModuleEvaluator::eval_js(
184                    ctx.clone(),
185                    "test",
186                    r#"
187                        import { availableParallelism } from 'os';
188
189                        export async function test() {
190                            return availableParallelism()
191                        }
192                    "#,
193                )
194                .await
195                .unwrap();
196
197                let result = call_test::<usize, _>(&ctx, &module, ()).await;
198
199                assert!(result > 0);
200            })
201        })
202        .await;
203    }
204
205    #[tokio::test]
206    async fn test_eol() {
207        test_async_with(|ctx| {
208            Box::pin(async move {
209                ModuleEvaluator::eval_rust::<OsModule>(ctx.clone(), "os")
210                    .await
211                    .unwrap();
212
213                let module = ModuleEvaluator::eval_js(
214                    ctx.clone(),
215                    "test",
216                    r#"
217                        import { EOL } from 'os';
218
219                        export async function test() {
220                            return EOL
221                        }
222                    "#,
223                )
224                .await
225                .unwrap();
226
227                let result = call_test::<String, _>(&ctx, &module, ()).await;
228                assert!(result == EOL);
229            })
230        })
231        .await;
232    }
233
234    #[tokio::test]
235    async fn test_arch() {
236        test_async_with(|ctx| {
237            Box::pin(async move {
238                ModuleEvaluator::eval_rust::<OsModule>(ctx.clone(), "os")
239                    .await
240                    .unwrap();
241
242                let module = ModuleEvaluator::eval_js(
243                    ctx.clone(),
244                    "test",
245                    r#"
246                        import { arch } from 'os';
247
248                        export async function test() {
249                            return arch()
250                        }
251                    "#,
252                )
253                .await
254                .unwrap();
255
256                let result = call_test::<String, _>(&ctx, &module, ()).await;
257
258                assert!(!result.is_empty()); // Format is platform dependant
259            })
260        })
261        .await;
262    }
263}