Skip to main content

ferrijs_std/tty/
mod.rs

1// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3use crate::utils::module::{export_default, ModuleInfo};
4use rquickjs::{
5    module::{Declarations, Exports, ModuleDef},
6    prelude::Func,
7    Ctx, Result,
8};
9
10fn isatty(fd: i32) -> bool {
11    unsafe { libc::isatty(fd) != 0 }
12}
13
14pub struct TtyModule;
15
16impl ModuleDef for TtyModule {
17    fn declare(declare: &Declarations<'_>) -> Result<()> {
18        declare.declare("isatty")?;
19        declare.declare("default")?;
20        Ok(())
21    }
22
23    fn evaluate<'js>(ctx: &Ctx<'js>, exports: &Exports<'js>) -> Result<()> {
24        export_default(ctx, exports, |default| {
25            default.set("isatty", Func::from(isatty))?;
26            Ok(())
27        })
28    }
29}
30
31impl From<TtyModule> for ModuleInfo<TtyModule> {
32    fn from(val: TtyModule) -> Self {
33        ModuleInfo {
34            name: "tty",
35            module: val,
36        }
37    }
38}
39
40#[cfg(test)]
41mod tests {
42    use crate::tty::TtyModule;
43    use crate::test::{call_test, test_async_with, ModuleEvaluator};
44    use std::io::{stderr, stdin, stdout, IsTerminal};
45
46    #[tokio::test]
47    async fn test_isatty() {
48        test_async_with(|ctx| {
49            Box::pin(async move {
50                ModuleEvaluator::eval_rust::<TtyModule>(ctx.clone(), "tty")
51                    .await
52                    .unwrap();
53
54                let module = ModuleEvaluator::eval_js(
55                    ctx.clone(),
56                    "test",
57                    r#"
58                        import { isatty } from 'tty';
59
60                        export async function test() {
61                            return new Array(3).fill(0).map((_, i) => +isatty(i)).join('')
62                        }
63                    "#,
64                )
65                .await
66                .unwrap();
67                let expect = [
68                    stdin().is_terminal(),
69                    stdout().is_terminal(),
70                    stderr().is_terminal(),
71                ]
72                .map(|i| (i as u8).to_string())
73                .join("");
74                let result = call_test::<String, _>(&ctx, &module, ()).await;
75                assert_eq!(result, expect);
76            })
77        })
78        .await;
79    }
80}