aboutsummaryrefslogtreecommitdiff
path: root/src/annotation/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/annotation/mod.rs')
-rw-r--r--src/annotation/mod.rs50
1 files changed, 34 insertions, 16 deletions
diff --git a/src/annotation/mod.rs b/src/annotation/mod.rs
index 0139cf3..af8b4bf 100644
--- a/src/annotation/mod.rs
+++ b/src/annotation/mod.rs
@@ -19,6 +19,13 @@
//! in a generic setting, there isn't much to do with a `FieldDescription` other than display it. a
//! typical use might look something like:
//! ```
+//! #[cfg(feature="std")]
+//! # {
+//! use core::fmt;
+//!
+//! use yaxpeax_arch::annotation::{AnnotatingDecoder, VecSink};
+//! use yaxpeax_arch::{Arch, Reader, U8Reader};
+//!
//! fn show_field_descriptions<A: Arch>(decoder: A::Decoder, buf: &[u8])
//! where
//! A::Decoder: AnnotatingDecoder<A>,
@@ -32,9 +39,10 @@
//!
//! println!("decoded instruction {}", inst);
//! for (start, end, desc) in sink.records.iter() {
-//! println(" bits [{}, {}]: {}", start, end, desc);
+//! println!(" bits [{}, {}]: {}", start, end, desc);
//! }
//! }
+//! # }
//! ```
//!
//! note that the range `[start, end]` for a reported span is _inclusive_. the `end`-th bit of a
@@ -68,7 +76,7 @@ use crate::{Arch, Reader};
use core::fmt::Display;
-/// implementors of `DescriptionSink` receive descriptions of an instruction's disassembly process
+/// implementers of `DescriptionSink` receive descriptions of an instruction's disassembly process
/// and relevant offsets in the bitstream being decoded. descriptions are archtecture-specific, and
/// architectures are expected to be able to turn the bit-level `start` and `width` values into a
/// meaningful description of bits in the original instruction stream.
@@ -86,24 +94,34 @@ impl<T> DescriptionSink<T> for NullSink {
fn record(&mut self, _start: u32, _end: u32, _description: T) { }
}
-#[cfg(feature = "std")]
-pub struct VecSink<T: Clone + Display> {
- pub records: std::vec::Vec<(u32, u32, T)>
-}
+#[cfg(feature = "alloc")]
+mod vec_sink {
+ use alloc::vec::Vec;
+ use core::fmt::Display;
+ use crate::annotation::DescriptionSink;
-#[cfg(feature = "std")]
-impl<T: Clone + Display> VecSink<T> {
- pub fn new() -> Self {
- VecSink { records: std::vec::Vec::new() }
+ pub struct VecSink<T: Clone + Display> {
+ pub records: Vec<(u32, u32, T)>
+ }
+
+ impl<T: Clone + Display> VecSink<T> {
+ pub fn new() -> Self {
+ VecSink { records: Vec::new() }
+ }
+
+ pub fn into_inner(self) -> Vec<(u32, u32, T)> {
+ self.records
+ }
}
-}
-#[cfg(feature = "std")]
-impl<T: Clone + Display> DescriptionSink<T> for VecSink<T> {
- fn record(&mut self, start: u32, end: u32, description: T) {
- self.records.push((start, end, description));
+ impl<T: Clone + Display> DescriptionSink<T> for VecSink<T> {
+ fn record(&mut self, start: u32, end: u32, description: T) {
+ self.records.push((start, end, description));
+ }
}
}
+#[cfg(feature = "alloc")]
+pub use vec_sink::VecSink;
pub trait FieldDescription {
fn id(&self) -> u32;
@@ -113,7 +131,7 @@ pub trait FieldDescription {
/// an interface to decode [`Arch::Instruction`] words from a reader of [`Arch::Word`]s, with the
/// decoder able to report descriptions of bits or fields in the instruction to a sink implementing
/// [`DescriptionSink`]. the sink may be [`NullSink`] to discard provided data. decoding with a
-/// `NullSink` should behave identically to `Decoder::decode_into`. implementors are recommended to
+/// `NullSink` should behave identically to `Decoder::decode_into`. implementers are recommended to
/// implement `Decoder::decode_into` as a call to `AnnotatingDecoder::decode_with_annotation` if
/// implementing both traits.
pub trait AnnotatingDecoder<A: Arch + ?Sized> {