virtual_console_lib/
logo.rs

1// Copyright 2025 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::log::LogClient;
6use anyhow::Error;
7use std::io::sink;
8use term_model::ansi::Processor;
9use term_model::event::EventListener;
10
11const LOGO_TEXT: &str = "
12\r
13                                      ff    ff  ff\r
14                                   ff  fffffffffff ff\r
15                                  f ffffffffffffffff f\r
16                                ff ffffffffffffffffffff\r
17                                f fffffffff        ffff\r
18                               f ffffffff            ff\r
19                               f fffffff              f\r
20                              ff fffffff\r
21                              f  ffffff\r
22                               fffffffff             f\r
23                        fffffff                    fff\r
24                    ffffffffffffffffffffffff   ffffff\r
25                 ffffffffffffffffffffffffffffffffff\r
26                ffffff   fffffff         ffffff\r
27               fffff  fff      ffffffffff\r
28              fffff ff         fffffff  f\r
29              ffff fff         fffffff ff\r
30             fffff ff         ffffffff f\r
31              ffff fff       ffffffff  f\r
32              ffff ffffffffffffffffff f\r
33               ffff fffffffffffffff  f\r
34                fffff  ffffffffff  ff\r
35                  fffff         fff\r
36                    fffffffffffff\r
37";
38
39pub struct Logo;
40impl Logo {
41    pub fn start<T: LogClient>(client: &T, id: u32) -> Result<(), Error>
42    where
43        <T as LogClient>::Listener: EventListener,
44    {
45        let client = client.clone();
46        let terminal =
47            client.create_terminal(id, "logo".to_string()).expect("failed to create terminal");
48        let term = terminal.clone_term();
49
50        let mut sink = sink();
51        let mut parser = Processor::new();
52        {
53            let mut term = term.borrow_mut();
54            for byte in LOGO_TEXT.as_bytes() {
55                parser.advance(&mut *term, *byte, &mut sink);
56            }
57            client.request_update(id);
58        }
59        Ok(())
60    }
61}
62
63#[cfg(test)]
64mod tests {
65    use super::*;
66    use crate::colors::ColorScheme;
67    use crate::terminal::Terminal;
68    use fuchsia_async as fasync;
69    use term_model::event::Event;
70
71    #[derive(Default)]
72    struct TestListener;
73
74    impl EventListener for TestListener {
75        fn send_event(&self, _event: Event) {}
76    }
77
78    #[derive(Default, Clone)]
79    struct TestLogClient;
80
81    impl LogClient for TestLogClient {
82        type Listener = TestListener;
83
84        fn create_terminal(
85            &self,
86            _id: u32,
87            title: String,
88        ) -> Result<Terminal<Self::Listener>, Error> {
89            Ok(Terminal::new(TestListener::default(), title, ColorScheme::default(), 1024, None))
90        }
91        fn request_update(&self, _id: u32) {}
92    }
93
94    #[fasync::run_singlethreaded(test)]
95    async fn can_start_logo() -> Result<(), Error> {
96        let client = TestLogClient::default();
97        let _ = Logo::start(&client, 0)?;
98        Ok(())
99    }
100}