Merge branch 'no_std' into 'master'

no_std support

Closes #1

See merge request davidbittner/ansi-parser!5
This commit is contained in:
David Bittner
2020-10-05 18:38:53 +00:00
8 changed files with 161 additions and 32 deletions

98
Cargo.lock generated
View File

@@ -4,29 +4,113 @@
name = "ansi-parser" name = "ansi-parser"
version = "0.6.5" version = "0.6.5"
dependencies = [ dependencies = [
"nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "heapless",
"nom",
]
[[package]]
name = "as-slice"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb4d1c23475b74e3672afa8c2be22040b8b7783ad9b461021144ed10a46bb0e6"
dependencies = [
"generic-array 0.12.3",
"generic-array 0.13.2",
"generic-array 0.14.4",
"stable_deref_trait",
]
[[package]]
name = "byteorder"
version = "1.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
[[package]]
name = "generic-array"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
dependencies = [
"typenum",
]
[[package]]
name = "generic-array"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd"
dependencies = [
"typenum",
]
[[package]]
name = "generic-array"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
dependencies = [
"typenum",
"version_check 0.9.2",
]
[[package]]
name = "hash32"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4041af86e63ac4298ce40e5cca669066e75b6f1aa3390fe2561ffa5e1d9f4cc"
dependencies = [
"byteorder",
]
[[package]]
name = "heapless"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74911a68a1658cfcfb61bc0ccfbd536e3b6e906f8c2f7883ee50157e3e2184f1"
dependencies = [
"as-slice",
"generic-array 0.13.2",
"hash32",
"stable_deref_trait",
] ]
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.2.0" version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39"
[[package]] [[package]]
name = "nom" name = "nom"
version = "4.2.3" version = "4.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
dependencies = [ dependencies = [
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "memchr",
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "version_check 0.1.5",
] ]
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "typenum"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.1.5" version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
[metadata] [[package]]
"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" name = "version_check"
"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" version = "0.9.2"
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"

View File

@@ -11,3 +11,8 @@ edition = "2018"
[dependencies] [dependencies]
nom = "4.2.3" nom = "4.2.3"
heapless = "0.5.6"
[features]
std = []
default = ["std"]

View File

@@ -45,4 +45,8 @@ fn main() {
} }
} }
} }
``` ```
# `no_std` support
`no_std` is supported via disabling the `std` feature in your `Cargo.toml`.

View File

@@ -1,8 +1,10 @@
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
use heapless::{Vec, consts::U5};
///The following are the implemented ANSI escape sequences. More to be added. ///The following are the implemented ANSI escape sequences. More to be added.
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, Clone)]
pub enum AnsiSequence { pub enum AnsiSequence {
CursorPos(u32, u32), CursorPos(u32, u32),
CursorUp(u32), CursorUp(u32),
@@ -13,7 +15,7 @@ pub enum AnsiSequence {
CursorRestore, CursorRestore,
EraseDisplay, EraseDisplay,
EraseLine, EraseLine,
SetGraphicsMode(Vec<u32>), SetGraphicsMode(Vec<u8, U5>),
SetMode(u8), SetMode(u8),
ResetMode(u8), ResetMode(u8),
HideCursor, HideCursor,
@@ -54,9 +56,9 @@ pub enum AnsiSequence {
SetTopAndBottom(u32, u32), SetTopAndBottom(u32, u32),
} }
use std::fmt::Display; use core::fmt::{Display, Formatter, Result as DisplayResult};
impl Display for AnsiSequence { impl Display for AnsiSequence {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, formatter: &mut Formatter) -> DisplayResult {
write!(formatter, "\u{1b}")?; write!(formatter, "\u{1b}")?;
use AnsiSequence::*; use AnsiSequence::*;
@@ -181,7 +183,7 @@ pub enum Output<'a> {
} }
impl<'a> Display for Output<'a> { impl<'a> Display for Output<'a> {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, formatter: &mut Formatter) -> DisplayResult {
use Output::*; use Output::*;
match self { match self {
TextBlock(txt) => write!(formatter, "{}", txt), TextBlock(txt) => write!(formatter, "{}", txt),

View File

@@ -1,4 +1,5 @@
#![recursion_limit="256"] #![recursion_limit="256"]
#![cfg_attr(not(any(feature = "std", test)), no_std)]
mod enums; mod enums;
mod parsers; mod parsers;
@@ -20,3 +21,4 @@ mod traits;
pub use enums::*; pub use enums::*;
pub use traits::*; pub use traits::*;
pub use parsers::parse_escape;

View File

@@ -1,9 +1,10 @@
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
use crate::{AnsiSequence, Output}; use crate::AnsiSequence;
use std::convert::TryInto; use core::convert::TryInto;
use heapless::Vec;
use nom::*; use nom::*;
macro_rules! tag_parser { macro_rules! tag_parser {
@@ -97,7 +98,9 @@ named!(
tag!("[") >> tag!("[") >>
val: parse_int >> val: parse_int >>
tag!("m") >> tag!("m") >>
(AnsiSequence::SetGraphicsMode(vec![val])) val: expr_res!(val.try_into()) >>
conv: expr_res!(Vec::from_slice(&[val])) >>
(AnsiSequence::SetGraphicsMode(conv))
) )
); );
@@ -109,7 +112,13 @@ named!(
tag!(";") >> tag!(";") >>
val2: parse_int >> val2: parse_int >>
tag!("m") >> tag!("m") >>
(AnsiSequence::SetGraphicsMode(vec![val1, val2])) val1: expr_res!(val1.try_into()) >>
val2: expr_res!(val2.try_into()) >>
conv: expr_res!(Vec::from_slice(&[
val1,
val2,
])) >>
(AnsiSequence::SetGraphicsMode(conv))
) )
); );
@@ -123,7 +132,15 @@ named!(
tag!(";") >> tag!(";") >>
val3: parse_int >> val3: parse_int >>
tag!("m") >> tag!("m") >>
(AnsiSequence::SetGraphicsMode(vec![val1, val2, val3])) val1: expr_res!(val1.try_into()) >>
val2: expr_res!(val2.try_into()) >>
val3: expr_res!(val3.try_into()) >>
conv: expr_res!(Vec::from_slice(&[
val1,
val2,
val3,
])) >>
(AnsiSequence::SetGraphicsMode(conv))
) )
); );
@@ -131,11 +148,10 @@ named!(
graphics_mode4<&str, AnsiSequence>, graphics_mode4<&str, AnsiSequence>,
do_parse!( do_parse!(
tag!("[m") >> tag!("[m") >>
(AnsiSequence::SetGraphicsMode(vec![])) (AnsiSequence::SetGraphicsMode(Vec::new()))
) )
); );
named!( named!(
graphics_mode5<&str, AnsiSequence>, graphics_mode5<&str, AnsiSequence>,
do_parse!( do_parse!(
@@ -150,7 +166,19 @@ named!(
tag!(";") >> tag!(";") >>
val5: parse_int >> val5: parse_int >>
tag!("m") >> tag!("m") >>
(AnsiSequence::SetGraphicsMode(vec![val1, val2, val3, val4, val5])) val1: expr_res!(val1.try_into()) >>
val2: expr_res!(val2.try_into()) >>
val3: expr_res!(val3.try_into()) >>
val4: expr_res!(val4.try_into()) >>
val5: expr_res!(val5.try_into()) >>
conv: expr_res!(Vec::from_slice(&[
val1,
val2,
val3,
val4,
val5,
])) >>
(AnsiSequence::SetGraphicsMode(conv))
) )
); );
@@ -169,7 +197,7 @@ named!(
named!( named!(
set_mode<&str, AnsiSequence>, set_mode<&str, AnsiSequence>,
do_parse!( do_parse!(
tag_s!("[=") >> tag!("[=") >>
mode: parse_int >> mode: parse_int >>
conv: expr_res!(mode.try_into()) >> conv: expr_res!(mode.try_into()) >>
tag!("h") >> tag!("h") >>
@@ -180,7 +208,7 @@ named!(
named!( named!(
reset_mode<&str, AnsiSequence>, reset_mode<&str, AnsiSequence>,
do_parse!( do_parse!(
tag_s!("[=") >> tag!("[=") >>
mode: parse_int >> mode: parse_int >>
conv: expr_res!(mode.try_into()) >> conv: expr_res!(mode.try_into()) >>
tag!("l") >> tag!("l") >>
@@ -296,10 +324,10 @@ named!(
); );
named!( named!(
pub parse_escape<&str, Output>, pub parse_escape<&str, AnsiSequence>,
do_parse!( do_parse!(
tag_s!("\u{1b}") >> tag!("\u{1b}") >>
seq: combined >> seq: combined >>
(Output::Escape(seq)) (seq)
) )
); );

View File

@@ -1,5 +1,8 @@
use super::*; use crate::{
use crate::*; enums::{AnsiSequence, Output},
parsers::parse_escape,
traits::AnsiParser,
};
use std::fmt::Write; use std::fmt::Write;

View File

@@ -2,19 +2,20 @@ use crate::enums::{Output};
use crate::parsers::parse_escape; use crate::parsers::parse_escape;
pub trait AnsiParser { pub trait AnsiParser {
fn ansi_parse<'a>(&'a self) -> AnsiParseIterator<'a>; fn ansi_parse(&self) -> AnsiParseIterator<'_>;
} }
impl AnsiParser for str { impl AnsiParser for str {
fn ansi_parse<'a>(&'a self) -> AnsiParseIterator<'a> { fn ansi_parse(&self) -> AnsiParseIterator<'_> {
AnsiParseIterator { AnsiParseIterator {
dat: self dat: self
} }
} }
} }
#[cfg(any(feature = "std", test))]
impl AnsiParser for String { impl AnsiParser for String {
fn ansi_parse<'a>(&'a self) -> AnsiParseIterator<'a> { fn ansi_parse(&self) -> AnsiParseIterator<'_> {
AnsiParseIterator { AnsiParseIterator {
dat: self dat: self
} }
@@ -40,7 +41,7 @@ impl<'a> Iterator for AnsiParseIterator<'a> {
if let Ok(ret) = res { if let Ok(ret) = res {
self.dat = &ret.0; self.dat = &ret.0;
Some(ret.1) Some(Output::Escape(ret.1))
}else{ }else{
let pos = self.dat[(loc+1)..].find('\u{1b}'); let pos = self.dat[(loc+1)..].find('\u{1b}');
if let Some(loc) = pos { if let Some(loc) = pos {