      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127

    //! Simple abstractions for the IO operations.
    //!
    //! Basically it just a replacement for the std::io that is usable from
    //! the `no_std` environment.

    use crate::rust::result;

    #[cfg(feature="std")]
    use crate::rust::io;

    #[cfg(not(feature="std"))]
    use crate::rust::vec::Vec;

    /// IO specific error.
    #[derive(Debug)]
    pub enum Error {
    	/// Some unexpected data left in the buffer after reading all data.
    	TrailingData,

    	/// Unexpected End-Of-File
    	UnexpectedEof,

    	/// Invalid data is encountered.
    	InvalidData,

    	#[cfg(feature = "std")]
    	IoError(io::Error),
    }

    /// IO specific Result.
    pub type Result<T> = result::Result<T, Error>;

    pub trait Write {
    	/// Write a buffer of data into this write.
    	///
    	/// All data is written at once.
    	fn write(&mut self, buf: &[u8]) -> Result<()>;
    }

    pub trait Read {
    	/// Read a data from this read to a buffer.
    	///
    	/// If there is not enough data in this read then `UnexpectedEof` will be returned.
    	fn read(&mut self, buf: &mut [u8]) -> Result<()>;
    }

    /// Reader that saves the last position.
    pub struct Cursor<T> {
    	inner: T,
    	pos: usize,
    }

    impl<T> Cursor<T> {
    	pub fn new(inner: T) -> Cursor<T> {
    		Cursor {
    			inner,
    			pos: 0,
    		}
    	}

    	pub fn position(&self) -> usize {
    		self.pos
    	}
    }

    impl<T: AsRef<[u8]>> Read for Cursor<T> {
    	fn read(&mut self, buf: &mut [u8]) -> Result<()> {
    		let slice = self.inner.as_ref();
    		let remainder = slice.len() - self.pos;
    		let requested = buf.len();
    		if requested > remainder {
    			return Err(Error::UnexpectedEof);
    		}
    		buf.copy_from_slice(&slice[self.pos..(self.pos + requested)]);
    		self.pos += requested;
    		Ok(())
    	}
    }

    #[cfg(not(feature = "std"))]
    impl Write for Vec<u8> {
    	fn write(&mut self, buf: &[u8]) -> Result<()> {
    		self.extend(buf);
    		Ok(())
    	}
    }

    #[cfg(feature = "std")]
    impl<T: io::Read> Read for T {
    	fn read(&mut self, buf: &mut [u8]) -> Result<()> {
    		self.read_exact(buf)
    			.map_err(Error::IoError)
    	}
    }

    #[cfg(feature = "std")]
    impl<T: io::Write> Write for T {
    	fn write(&mut self, buf: &[u8]) -> Result<()> {
    		self.write_all(buf).map_err(Error::IoError)
    	}
    }

    #[cfg(test)]
    mod tests {
    	use super::*;

    	#[test]
    	fn cursor() {
    		let mut cursor = Cursor::new(vec![0xFFu8, 0x7Fu8]);
    		assert_eq!(cursor.position(), 0);

    		let mut buf = [0u8];
    		assert!(cursor.read(&mut buf[..]).is_ok());
    		assert_eq!(cursor.position(), 1);
    		assert_eq!(buf[0], 0xFFu8);
    		assert!(cursor.read(&mut buf[..]).is_ok());
    		assert_eq!(buf[0], 0x7Fu8);
    		assert_eq!(cursor.position(), 2);
    	}

    	#[test]
    	fn overflow_in_cursor() {
    		let mut cursor = Cursor::new(vec![0u8]);
    		let mut buf = [0, 1, 2];
    		assert!(cursor.read(&mut buf[..]).is_err());
    	}
    }

# Help

## Keyboard Shortcuts

`?`
  Show this help dialog
`S`
  Focus the search field
`↑`
  Move up in search results
`↓`
  Move down in search results
`↹`
  Switch tab
`⏎`
  Go to active search result
`+`
  Expand all sections
`-`
  Collapse all sections

## Search Tricks

Prefix searches with a type followed by a colon (e.g., `fn:`) to restrict the search to a given type.

Accepted types are: `fn`, `mod`, `struct`, `enum`, `trait`, `type`, `macro`, and `const`.

Search functions by type signature (e.g., `vec -> usize` or `* -> vec`)

Search multiple things at once by splitting your query with comma (e.g., `str,u8` or `String,struct:Vec,test`)