xref: /linux/samples/rust/rust_print_main.rs (revision e3610441d1fb47b1f00e4c38bdf333176e824729)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 //! Rust printing macros sample.
4 
5 use kernel::pr_cont;
6 use kernel::prelude::*;
7 
8 module! {
9     type: RustPrint,
10     name: "rust_print",
11     author: "Rust for Linux Contributors",
12     description: "Rust printing macros sample",
13     license: "GPL",
14 }
15 
16 struct RustPrint;
17 
18 #[expect(clippy::disallowed_macros)]
19 fn arc_print() -> Result {
20     use kernel::sync::*;
21 
22     let a = Arc::new(1, GFP_KERNEL)?;
23     let b = UniqueArc::new("hello, world", GFP_KERNEL)?;
24 
25     // Prints the value of data in `a`.
26     pr_info!("{}", a);
27 
28     // Uses ":?" to print debug fmt of `b`.
29     pr_info!("{:?}", b);
30 
31     let a: Arc<&str> = b.into();
32     let c = a.clone();
33 
34     // Uses `dbg` to print, will move `c` (for temporary debugging purposes).
35     dbg!(c);
36 
37     {
38         // `Arc` can be used to delegate dynamic dispatch and the following is an example.
39         // Both `i32` and `&str` implement `Display`. This enables us to express a unified
40         // behaviour, contract or protocol on both `i32` and `&str` into a single `Arc` of
41         // type `Arc<dyn Display>`.
42 
43         use core::fmt::Display;
44         fn arc_dyn_print(arc: &Arc<dyn Display>) {
45             pr_info!("Arc<dyn Display> says {arc}");
46         }
47 
48         let a_i32_display: Arc<dyn Display> = Arc::new(42i32, GFP_KERNEL)?;
49         let a_str_display: Arc<dyn Display> = a.clone();
50 
51         arc_dyn_print(&a_i32_display);
52         arc_dyn_print(&a_str_display);
53     }
54 
55     // Pretty-prints the debug formatting with lower-case hexadecimal integers.
56     pr_info!("{:#x?}", a);
57 
58     Ok(())
59 }
60 
61 impl kernel::Module for RustPrint {
62     fn init(_module: &'static ThisModule) -> Result<Self> {
63         pr_info!("Rust printing macros sample (init)\n");
64 
65         pr_emerg!("Emergency message (level 0) without args\n");
66         pr_alert!("Alert message (level 1) without args\n");
67         pr_crit!("Critical message (level 2) without args\n");
68         pr_err!("Error message (level 3) without args\n");
69         pr_warn!("Warning message (level 4) without args\n");
70         pr_notice!("Notice message (level 5) without args\n");
71         pr_info!("Info message (level 6) without args\n");
72 
73         pr_info!("A line that");
74         pr_cont!(" is continued");
75         pr_cont!(" without args\n");
76 
77         pr_emerg!("{} message (level {}) with args\n", "Emergency", 0);
78         pr_alert!("{} message (level {}) with args\n", "Alert", 1);
79         pr_crit!("{} message (level {}) with args\n", "Critical", 2);
80         pr_err!("{} message (level {}) with args\n", "Error", 3);
81         pr_warn!("{} message (level {}) with args\n", "Warning", 4);
82         pr_notice!("{} message (level {}) with args\n", "Notice", 5);
83         pr_info!("{} message (level {}) with args\n", "Info", 6);
84 
85         pr_info!("A {} that", "line");
86         pr_cont!(" is {}", "continued");
87         pr_cont!(" with {}\n", "args");
88 
89         arc_print()?;
90 
91         trace::trace_rust_sample_loaded(42);
92 
93         Ok(RustPrint)
94     }
95 }
96 
97 impl Drop for RustPrint {
98     fn drop(&mut self) {
99         pr_info!("Rust printing macros sample (exit)\n");
100     }
101 }
102 
103 mod trace {
104     use kernel::ffi::c_int;
105 
106     kernel::declare_trace! {
107         /// # Safety
108         ///
109         /// Always safe to call.
110         unsafe fn rust_sample_loaded(magic: c_int);
111     }
112 
113     pub(crate) fn trace_rust_sample_loaded(magic: i32) {
114         // SAFETY: Always safe to call.
115         unsafe { rust_sample_loaded(magic as c_int) }
116     }
117 }
118