mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-02-24 15:02:20 +01:00
Add PrintableString utility
Strings defined by third parties may contain control characters. Provide a wrapper such that these are replaced when displayed. Useful in node aliases and offer fields.
This commit is contained in:
parent
50aeee5afb
commit
48bb9edba1
3 changed files with 47 additions and 10 deletions
|
@ -31,6 +31,7 @@ use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer, MaybeReadable}
|
|||
use crate::util::logger::{Logger, Level};
|
||||
use crate::util::events::{Event, EventHandler, MessageSendEvent, MessageSendEventsProvider};
|
||||
use crate::util::scid_utils::{block_from_scid, scid_from_parts, MAX_SCID_BLOCK};
|
||||
use crate::util::string::PrintableString;
|
||||
|
||||
use crate::io;
|
||||
use crate::io_extras::{copy, sink};
|
||||
|
@ -1022,23 +1023,17 @@ pub struct NodeAlias(pub [u8; 32]);
|
|||
|
||||
impl fmt::Display for NodeAlias {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
let control_symbol = core::char::REPLACEMENT_CHARACTER;
|
||||
let first_null = self.0.iter().position(|b| *b == 0).unwrap_or(self.0.len());
|
||||
let bytes = self.0.split_at(first_null).0;
|
||||
match core::str::from_utf8(bytes) {
|
||||
Ok(alias) => {
|
||||
for c in alias.chars() {
|
||||
let mut bytes = [0u8; 4];
|
||||
let c = if !c.is_control() { c } else { control_symbol };
|
||||
f.write_str(c.encode_utf8(&mut bytes))?;
|
||||
}
|
||||
},
|
||||
Ok(alias) => PrintableString(alias).fmt(f)?,
|
||||
Err(_) => {
|
||||
use core::fmt::Write;
|
||||
for c in bytes.iter().map(|b| *b as char) {
|
||||
// Display printable ASCII characters
|
||||
let mut bytes = [0u8; 4];
|
||||
let control_symbol = core::char::REPLACEMENT_CHARACTER;
|
||||
let c = if c >= '\x20' && c <= '\x7e' { c } else { control_symbol };
|
||||
f.write_str(c.encode_utf8(&mut bytes))?;
|
||||
f.write_char(c)?;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -21,6 +21,7 @@ pub mod ser;
|
|||
pub mod message_signing;
|
||||
pub mod invoice;
|
||||
pub mod persist;
|
||||
pub mod string;
|
||||
pub mod wakers;
|
||||
|
||||
pub(crate) mod atomic_counter;
|
||||
|
|
41
lightning/src/util/string.rs
Normal file
41
lightning/src/util/string.rs
Normal file
|
@ -0,0 +1,41 @@
|
|||
// This file is Copyright its original authors, visible in version control
|
||||
// history.
|
||||
//
|
||||
// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
|
||||
// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
|
||||
// You may not use this file except in accordance with one or both of these
|
||||
// licenses.
|
||||
|
||||
//! Utilities for strings.
|
||||
|
||||
use core::fmt;
|
||||
|
||||
/// A string that displays only printable characters, replacing control characters with
|
||||
/// [`core::char::REPLACEMENT_CHARACTER`].
|
||||
pub struct PrintableString<'a>(pub &'a str);
|
||||
|
||||
impl<'a> fmt::Display for PrintableString<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
use core::fmt::Write;
|
||||
for c in self.0.chars() {
|
||||
let c = if c.is_control() { core::char::REPLACEMENT_CHARACTER } else { c };
|
||||
f.write_char(c)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::PrintableString;
|
||||
|
||||
#[test]
|
||||
fn displays_printable_string() {
|
||||
assert_eq!(
|
||||
format!("{}", PrintableString("I \u{1F496} LDK!\t\u{26A1}")),
|
||||
"I \u{1F496} LDK!\u{FFFD}\u{26A1}",
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue