lcd_rus/lib.rs
1#![no_std]
2#![warn(missing_docs)]
3#![doc = include_str!("../README.md")]
4
5/// Certain internals have to be exported for macros to work.
6#[doc(hidden)]
7pub mod internal;
8
9/// Get length of an array required to fit the LCD encoded characters.
10///
11/// This is normally only needed if you're encoding strings at runtime,
12/// but may also come in handy if you're writing your own macros.
13///
14/// It's worth noting that this function is not very optimized, both in
15/// terms of size and execution speed. As such, using it at runtime
16/// is discouraged.
17pub const fn lcd_length(s: &str) -> usize {
18 internal::utf8_len(s)
19}
20
21/// Convert a string into LCD encoding at runtime.
22///
23/// Takes a string to convert and a buffer to write transcoded characters to.
24/// You can call [lcd_length] to know how many characters you need space for.
25///
26/// Returns a result indicating if all of the characters were converted
27/// and how many were.
28///
29/// This interface is mostly provided for the sake of completeness; use the
30/// macros for compile time transformation if possible instead to avoid
31/// both runtime overhead and binary size increase.
32///
33/// Example
34///
35/// ```
36/// use lcd_rus::lcd_encode_runtime;
37///
38/// let mut buf = [0u8; 16];
39/// let len = lcd_encode_runtime(&mut buf, "Hello, мир!").unwrap();
40///
41/// // Print the message on your LCD; the function must take &[u8] rather than &str
42/// lcd.write_bytes(&mut delay, &buf[..len]);
43/// ```
44pub fn lcd_encode_runtime(output: &mut [u8], s: &str) -> Result<usize, usize> {
45 internal::str_to_lcd_runtime(output, s)
46}
47
48/// Convert a string literal into LCD encoding, storing result in a constant.
49///
50/// The produced constant will be of type `[u8; _]`.
51///
52/// [lcd_literal] is often more convenient to use.
53///
54/// This transformation is performed entirely at compile time;
55/// with correct optimization settings no code at all should be emitted.
56/// Strings containing unexpected characters will result in build failure.
57///
58/// The crate must be imported under its name for this macro to work.
59///
60/// # Example
61///
62/// ```
63/// use lcd_rus::{self, lcd_const};
64///
65/// // Declare the constant
66/// lcd_const!(MY_MSG, "Hello, мир!");
67///
68/// // Print the message on your LCD; the function must take &[u8] rather than &str
69/// lcd.print(&MY_MSG);
70/// ```
71#[macro_export]
72macro_rules! lcd_const {
73 ($id:ident, $s:literal) => {
74 const $id: [u8; lcd_rus::lcd_length($s)] =
75 lcd_rus::internal::str_to_lcd_const::<{ lcd_rus::lcd_length($s) }>($s);
76 };
77}
78
79/// Convert a string literal into LCD encoding, returning the result.
80///
81/// Return type is a `[u8; _]`.
82///
83/// This transformation is performed entirely at compile time with transformed string stored in a constant;
84/// with correct optimization settings no code at all should be emitted. Strings containing unexpected characters
85/// will result in build failure.
86///
87/// The crate must be imported under its name for this macro to work.
88///
89/// # Example
90///
91/// ```
92/// use lcd_rus::{self, lcd_literal};
93///
94/// // Print the message on your LCD; the function must take &[u8] rather than &str
95/// lcd.print(&lcd_literal!("Hello, мир!"));
96/// ```
97#[macro_export]
98macro_rules! lcd_literal {
99 ($s:literal) => {{
100 const STRING: [u8; lcd_rus::lcd_length($s)] =
101 lcd_rus::internal::str_to_lcd_const::<{ lcd_rus::lcd_length($s) }>($s);
102 STRING
103 }};
104}