(index<- )        ./libstd/rt/io/option.rs

   1  // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
   2  // file at the top-level directory of this distribution and at
   3  // http://rust-lang.org/COPYRIGHT.
   4  //
   5  // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
   6  // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
   7  // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
   8  // option. This file may not be copied, modified, or distributed
   9  // except according to those terms.
  10  
  11  //! Implementations of I/O traits for the Option type
  12  //!
  13  //! I/O constructors return option types to allow errors to be handled.
  14  //! These implementations allow e.g. `Option<FileStream>` to be used
  15  //! as a `Reader` without unwrapping the option first.
  16  //!
  17  //! # XXX Seek and Close
  18  
  19  use option::*;
  20  use super::{Reader, Writer, Listener, Acceptor};
  21  use super::{standard_error, PreviousIoError, io_error, read_error, IoError};
  22  
  23  fn prev_io_error() -> IoError {
  24      standard_error(PreviousIoError)
  25  }
  26  
  27  impl<W: Writer> Writer for Option<W> {
  28      fn write(&mut self, buf&[u8]) {
  29          match *self {
  30              Some(ref mut writer) => writer.write(buf),
  31              None => io_error::cond.raise(prev_io_error())
  32          }
  33      }
  34  
  35      fn flush(&mut self) {
  36          match *self {
  37              Some(ref mut writer) => writer.flush(),
  38              None => io_error::cond.raise(prev_io_error())
  39          }
  40      }
  41  }
  42  
  43  impl<R: Reader> Reader for Option<R> {
  44      fn read(&mut self, buf&mut [u8]) -> Option<uint> {
  45          match *self {
  46              Some(ref mut reader) => reader.read(buf),
  47              None => {
  48                  read_error::cond.raise(prev_io_error());
  49                  None
  50              }
  51          }
  52      }
  53  
  54      fn eof(&mut self) -> bool {
  55          match *self {
  56              Some(ref mut reader) => reader.eof(),
  57              None => {
  58                  io_error::cond.raise(prev_io_error());
  59                  true
  60              }
  61          }
  62      }
  63  }
  64  
  65  impl<T, A: Acceptor<T>, L: Listener<T, A>> Listener<T, A> for Option<L> {
  66      fn listen(self) -> Option<A> {
  67          match self {
  68              Some(listener) => listener.listen(),
  69              None => {
  70                  io_error::cond.raise(prev_io_error());
  71                  None
  72              }
  73          }
  74      }
  75  }
  76  
  77  impl<T, A: Acceptor<T>> Acceptor<T> for Option<A> {
  78      fn accept(&mut self) -> Option<T> {
  79          match *self {
  80              Some(ref mut acceptor) => acceptor.accept(),
  81              None => {
  82                  io_error::cond.raise(prev_io_error());
  83                  None
  84              }
  85          }
  86      }
  87  }
  88  
  89  #[cfg(test)]
  90  mod test {
  91      use option::*;
  92      use super::super::mem::*;
  93      use rt::test::*;
  94      use super::super::{PreviousIoError, io_error, read_error};
  95  
  96      #[test]
  97      fn test_option_writer() {
  98          do run_in_mt_newsched_task {
  99              let mut writer: Option<MemWriter> = Some(MemWriter::new());
 100              writer.write([0, 1, 2]);
 101              writer.flush();
 102              assert_eq!(writer.unwrap().inner(), ~[0, 1, 2]);
 103          }
 104      }
 105  
 106      #[test]
 107      fn test_option_writer_error() {
 108          do run_in_mt_newsched_task {
 109              let mut writer: Option<MemWriter> = None;
 110  
 111              let mut called = false;
 112              do io_error::cond.trap(|err| {
 113                  assert_eq!(err.kind, PreviousIoError);
 114                  called = true;
 115              }).inside {
 116                  writer.write([0, 0, 0]);
 117              }
 118              assert!(called);
 119  
 120              let mut called = false;
 121              do io_error::cond.trap(|err| {
 122                  assert_eq!(err.kind, PreviousIoError);
 123                  called = true;
 124              }).inside {
 125                  writer.flush();
 126              }
 127              assert!(called);
 128          }
 129      }
 130  
 131      #[test]
 132      fn test_option_reader() {
 133          do run_in_mt_newsched_task {
 134              let mut reader: Option<MemReader> = Some(MemReader::new(~[0, 1, 2, 3]));
 135              let mut buf = [0, 0];
 136              reader.read(buf);
 137              assert_eq!(buf, [0, 1]);
 138              assert!(!reader.eof());
 139          }
 140      }
 141  
 142      #[test]
 143      fn test_option_reader_error() {
 144          let mut reader: Option<MemReader> = None;
 145          let mut buf = [];
 146  
 147          let mut called = false;
 148          do read_error::cond.trap(|err| {
 149              assert_eq!(err.kind, PreviousIoError);
 150              called = true;
 151          }).inside {
 152              reader.read(buf);
 153          }
 154          assert!(called);
 155  
 156          let mut called = false;
 157          do io_error::cond.trap(|err| {
 158              assert_eq!(err.kind, PreviousIoError);
 159              called = true;
 160          }).inside {
 161              assert!(reader.eof());
 162          }
 163          assert!(called);
 164      }
 165  }