(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 }