From 103749d9330e6d6ec048118489925a50db2ab93f Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 20 Jul 2015 14:33:36 -0400 Subject: [PATCH] Improve documentation for std::io::Cursor Beef up the docs on the type, as well as adding examples for all methods. --- src/libstd/io/cursor.rs | 149 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 140 insertions(+), 9 deletions(-) diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs index f059b24baf6..4bb7d2ebd19 100644 --- a/src/libstd/io/cursor.rs +++ b/src/libstd/io/cursor.rs @@ -15,16 +15,67 @@ use cmp; use io::{self, SeekFrom, Error, ErrorKind}; use slice; -/// A `Cursor` is a type which wraps a non-I/O object to provide a `Seek` +/// A `Cursor` wraps another type and provides it with a [`Seek`][seek] /// implementation. /// -/// Cursors are typically used with memory buffer objects in order to allow -/// `Seek`, `Read`, and `Write` implementations. For example, common cursor types -/// include `Cursor>` and `Cursor<&[u8]>`. +/// [seek]: trait.Seek.html /// -/// Implementations of the I/O traits for `Cursor` are currently not generic -/// over `T` itself. Instead, specific implementations are provided for various -/// in-memory buffer types like `Vec` and `&[u8]`. +/// Cursors are typically used with in-memory buffers to allow them to +/// implement `Read` and/or `Write`, allowing these buffers to be used +/// anywhere you might use a reader or writer that does actual I/O. +/// +/// The standard library implements some I/O traits on various types which +/// are commonly used as a buffer, like `Cursor>` and `Cursor<&[u8]>`. +/// +/// # Examples +/// +/// We may want to write bytes to a [`File`][file] in our production +/// code, but use an in-memory buffer in our tests. We can do this with +/// `Cursor`: +/// +/// [file]: ../fs/struct.File.html +/// +/// ```no_run +/// use std::io::prelude::*; +/// use std::io::{self, SeekFrom}; +/// use std::fs::File; +/// +/// // a library function we've written +/// fn write_ten_bytes_at_end(writer: &mut W) -> io::Result<()> { +/// try!(writer.seek(SeekFrom::End(-10))); +/// +/// for i in 0..10 { +/// try!(writer.write(&[i])); +/// } +/// +/// // all went well +/// Ok(()) +/// } +/// +/// # fn foo() -> io::Result<()> { +/// // Here's some code that uses this library function. +/// // +/// // We might want to use a BufReader here for efficiency, but let's +/// // keep this example focused. +/// let mut file = try!(File::create("foo.txt")); +/// +/// try!(write_ten_bytes_at_end(&mut file)); +/// # Ok(()) +/// # } +/// +/// // now let's write a test +/// #[test] +/// fn test_writes_bytes() { +/// // setting up a real File is much more slow than an in-memory buffer, +/// // let's use a cursor instead +/// use std::io::Cursor; +/// let mut buff = Cursor::new(vec![0; 15]); +/// +/// write_ten_bytes(&mut buff).unwrap(); +/// +/// assert_eq!(&buff.get_ref()[5..15], &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); +/// } +/// ``` #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone, Debug)] pub struct Cursor { @@ -34,16 +85,50 @@ pub struct Cursor { impl Cursor { /// Creates a new cursor wrapping the provided underlying I/O object. + /// + /// # Examples + /// + /// ``` + /// use std::io::Cursor; + /// + /// let buff = Cursor::new(Vec::new()); + /// # fn force_inference(_: &Cursor>) {} + /// # force_inference(&buff); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn new(inner: T) -> Cursor { Cursor { pos: 0, inner: inner } } /// Consumes this cursor, returning the underlying value. + /// + /// # Examples + /// + /// ``` + /// use std::io::Cursor; + /// + /// let buff = Cursor::new(Vec::new()); + /// # fn force_inference(_: &Cursor>) {} + /// # force_inference(&buff); + /// + /// let vec = buff.into_inner(); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn into_inner(self) -> T { self.inner } /// Gets a reference to the underlying value in this cursor. + /// + /// # Examples + /// + /// ``` + /// use std::io::Cursor; + /// + /// let buff = Cursor::new(Vec::new()); + /// # fn force_inference(_: &Cursor>) {} + /// # force_inference(&buff); + /// + /// let reference = buff.get_ref(); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn get_ref(&self) -> &T { &self.inner } @@ -51,14 +136,60 @@ impl Cursor { /// /// Care should be taken to avoid modifying the internal I/O state of the /// underlying value as it may corrupt this cursor's position. + /// + /// # Examples + /// + /// ``` + /// use std::io::Cursor; + /// + /// let mut buff = Cursor::new(Vec::new()); + /// # fn force_inference(_: &Cursor>) {} + /// # force_inference(&buff); + /// + /// let reference = buff.get_mut(); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn get_mut(&mut self) -> &mut T { &mut self.inner } - /// Returns the current value of this cursor + /// Returns the current position of this cursor. + /// + /// # Examples + /// + /// ``` + /// use std::io::Cursor; + /// use std::io::prelude::*; + /// use std::io::SeekFrom; + /// + /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); + /// + /// assert_eq!(buff.position(), 0); + /// + /// buff.seek(SeekFrom::Current(2)).unwrap(); + /// assert_eq!(buff.position(), 2); + /// + /// buff.seek(SeekFrom::Current(-1)).unwrap(); + /// assert_eq!(buff.position(), 1); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn position(&self) -> u64 { self.pos } - /// Sets the value of this cursor + /// Sets the position of this cursor. + /// + /// # Examples + /// + /// ``` + /// use std::io::Cursor; + /// + /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); + /// + /// assert_eq!(buff.position(), 0); + /// + /// buff.set_position(2); + /// assert_eq!(buff.position(), 2); + /// + /// buff.set_position(4); + /// assert_eq!(buff.position(), 4); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn set_position(&mut self, pos: u64) { self.pos = pos; } }