<commit_before>export OSMain, Msg;

import azure::*;
import azure::bindgen::*;
import azure::cairo;
import azure::cairo::bindgen::*;
import comm::*;
import azure::cairo::cairo_surface_t;
import gfx::renderer::{Sink};

type OSMain = chan<Msg>;

enum Msg {
    BeginDrawing(chan<AzDrawTargetRef>),
    Draw(chan<AzDrawTargetRef>, AzDrawTargetRef),
    AddKeyHandler(chan<()>),
    Exit
}

fn OSMain() -> OSMain {
    on_osmain::<Msg> {|po|
        platform::runmain {||
            #debug("preparing to enter main loop");
	    mainloop(po);
        }
    }
}

fn mainloop(po: port<Msg>) {

    let mut key_handlers: [chan<()>] = [];

    sdl::init([
        sdl::init_video
    ]);

    let screen = sdl::video::set_video_mode(
        800, 600, 32,
        [sdl::video::swsurface],
        [sdl::video::doublebuf]);
    assert !ptr::is_null(screen);

    let surfaces = surface_set();

    loop {
        sdl::event::poll_event {|event|

            alt event {
              sdl::event::keydown_event(_) {
                key_handlers.iter {|key_ch|
                    key_ch.send(())
                }
              }
              _ { }
            }
        }

        // Handle messages
        if po.peek() {
            alt check po.recv() {
              AddKeyHandler(key_ch) {
                key_handlers += [key_ch];
              }
              BeginDrawing(sender) {
                lend_surface(surfaces, sender);
              }
              Draw(sender, dt) {
                return_surface(surfaces, dt);
                lend_surface(surfaces, sender);

                #debug("osmain: drawing to screen");
                assert surfaces.s1.surf.az_target == dt;
                let sdl_surf = surfaces.s1.surf.sdl_surf;

                cairo_surface_flush(surfaces.s1.surf.cairo_surf);
                sdl::video::unlock_surface(sdl_surf);
                sdl::video::blit_surface(sdl_surf, ptr::null(),
                                         screen, ptr::null());
                sdl::video::lock_surface(sdl_surf);
                sdl::video::flip(screen);
              }
              exit { break; }
            }
        }
    }
    destroy_surface(surfaces.s1.surf);
    destroy_surface(surfaces.s2.surf);
    sdl::quit();
}

#[doc = "
Implementation to allow the osmain channel to be used as a graphics
sink for the renderer
"]
impl OSMain of Sink for OSMain {
    fn begin_drawing(next_dt: chan<AzDrawTargetRef>) {
        self.send(BeginDrawing(next_dt))
    }
    fn draw(next_dt: chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef) {
        self.send(Draw(next_dt, draw_me))
    }
}

type surface_set = {
    mut s1: {
        surf: surface,
        have: bool
    },
    mut s2: {
        surf: surface,
        have: bool
    }
};

fn lend_surface(surfaces: surface_set, recvr: chan<AzDrawTargetRef>) {
    // We are in a position to lend out the surface?
    assert surfaces.s1.have;
    // Ok then take it
    let dt1 = surfaces.s1.surf.az_target;
    #debug("osmain: lending surface %?", dt1);
    recvr.send(dt1);
    // Now we don't have it
    surfaces.s1 = {
        have: false
        with surfaces.s1
    };
    // But we (hopefully) have another!
    surfaces.s1 <-> surfaces.s2;
    // Let's look
    assert surfaces.s1.have;
}

fn return_surface(surfaces: surface_set, dt: AzDrawTargetRef) {
    #debug("osmain: returning surface %?", dt);
    // We have room for a return
    assert surfaces.s1.have;
    assert !surfaces.s2.have;
    assert surfaces.s2.surf.az_target == dt;
    // Now we have it again
    surfaces.s2 = {
        have: true
        with surfaces.s2
    };
}

fn surface_set() -> surface_set {
    {
        mut s1: {
            surf: mk_surface(),
            have: true
        },
        mut s2: {
            surf: mk_surface(),
            have: true
        }
    }
}

type surface = {
    sdl_surf: *sdl::video::surface,
    cairo_surf: *cairo_surface_t,
    az_target: AzDrawTargetRef
};

fn mk_surface() -> surface {
    let sdl_surf = sdl::video::create_rgb_surface(
        [sdl::video::swsurface],
        800, 600, 32,
        0x00FF0000u32,
        0x0000FF00u32,
        0x000000FFu32,
        0x00000000u32
        );
    assert !ptr::is_null(sdl_surf);
    sdl::video::lock_surface(sdl_surf);
    let cairo_surf = unsafe {
        cairo_image_surface_create_for_data(
            unsafe::reinterpret_cast((*sdl_surf).pixels),
            cairo::CAIRO_FORMAT_RGB24,
            (*sdl_surf).w,
            (*sdl_surf).h,
            (*sdl_surf).pitch as libc::c_int
        )
    };
    assert !ptr::is_null(cairo_surf);

    let azure_target = AzCreateDrawTargetForCairoSurface(cairo_surf);
    assert !ptr::is_null(azure_target);

    {
        sdl_surf: sdl_surf,
        cairo_surf: cairo_surf,
        az_target: azure_target
    }
}

fn destroy_surface(surface: surface) {
    AzReleaseDrawTarget(surface.az_target);
    cairo_surface_destroy(surface.cairo_surf);
    sdl::video::unlock_surface(surface.sdl_surf);
    sdl::video::free_surface(surface.sdl_surf);
}

#[doc = "A function for spawning into the platform's main thread"]
fn on_osmain<T: send>(+f: fn~(comm::port<T>)) -> comm::chan<T> {
    let builder = task::builder();
    let opts = {
        sched: some({
            mode: task::osmain,
            native_stack_size: none
        })
        with task::get_opts(builder)
    };
    task::set_opts(builder, opts);
    ret task::run_listener(builder, f);
}

#[cfg(target_os = "linux")]
mod platform {
    fn runmain(f: fn()) {
        f()
    }
}

#[cfg(target_os = "macos")]
mod platform {
    use cocoa;
    import cocoa::base::*;

    mod NSApplication {
        fn sharedApplication() -> id {
            let klass = str::as_c_str("NSApplication") { |s|
                objc::objc_getClass(s)
            };

            let sel = str::as_c_str("sharedApplication") { |s|
                objc::sel_registerName(s)
            };

            let nsapp = objc::objc_msgSend(klass, sel);
            #debug("nsapp: %d", (nsapp as int));

	    ret nsapp;
        }
    }

    mod NSAutoreleasePool {
        fn alloc() -> id {
            let klass = str::as_c_str("NSAutoreleasePool") { |s|
                objc::objc_getClass(s)
            };
            let sel = str::as_c_str("alloc") { |s|
                objc::sel_registerName(s)
            };
            let pool = objc::objc_msgSend(klass, sel);
            #debug("autorelease pool: %?", pool);
            ret pool;
        }
        fn init(pool: id) {
            let sel = str::as_c_str("init") { |s|
                objc::sel_registerName(s)
            };
            objc::objc_msgSend(pool, sel);
        }
        fn release(pool: id) {
            let sel = str::as_c_str("release") { |s|
                objc::sel_registerName(s)
            };
            objc::objc_msgSend(pool, sel);
        }
    }

    mod NSApp {
         fn setDelegate(nsapp: id, main: id) {
	     #debug("NSApp::setDelegate");
	     let sel = str::as_c_str("setDelegate:") { |s|
	         objc::sel_registerName(s)
	     };
	     cocoa::msgSend1Id(nsapp, sel, main);
         }

         fn run(nsapp: id) {
	    #debug("NSApp::run");
            let sel = str::as_c_str("run") { |s|
                objc::sel_registerName(s)
            };
            objc::objc_msgSend(nsapp, sel);
         }
    }

    mod MainObj {
         crust fn applicationDidFinishLaunching(this: id, _sel: SEL) {
	     #debug("applicationDidFinishLaunching");

	     let fptr: *fn() = ptr::null();
	     str::as_c_str("fptr") { |name|
	         let outValue = unsafe { unsafe::reinterpret_cast(ptr::addr_of(fptr)) };
                 #debug("*fptr %?", outValue);
                 objc::object_getInstanceVariable(this, name, outValue)
             };

	     #debug("getting osmain fptr: %?", fptr);

	     unsafe {
	         // FIXME: We probably don't want to run the main routine in a crust function
                 (*fptr)();
             }
	 }

    	 fn create(f: fn()) -> id {
             let NSObject = str::as_c_str("NSObject") { |s|
	         objc::objc_getClass(s)
             };
	     let MainObj = str::as_c_str("MainObj") { |s|
	         objc::objc_allocateClassPair(NSObject, s, 0 as libc::size_t)
	     };

             // Add a field to our class to contain a pointer to a rust closure
	     let res = str::as_c_str("fptr") { |name|
                 str::as_c_str("^i") { |types|
                     objc::class_addIvar(MainObj, name,
                                         sys::size_of::<libc::uintptr_t>() as libc::size_t,
                                         16u8, types)
                 }
             };
 	     assert res == true;

	     let launchfn = str::as_c_str("applicationDidFinishLaunching:") { |s|
	         objc::sel_registerName(s)
	     };
	     let _ = str::as_c_str("@@:") { |types|
	         objc::class_addMethod(MainObj, launchfn, applicationDidFinishLaunching, types)
	     };

	     objc::objc_registerClassPair(MainObj);

             let sel = str::as_c_str("alloc") { |s|
                 objc::sel_registerName(s)
             };
             let mainobj = objc::objc_msgSend(MainObj, sel);

             let sel = str::as_c_str("init") { |s|
                 objc::sel_registerName(s)
             };
             objc::objc_msgSend(mainobj, sel);

	     let fptr = ptr::addr_of(f);
	     str::as_c_str("fptr") { |name|
	         #debug("setting osmain fptr: %?", fptr);
		 let value = unsafe { unsafe::reinterpret_cast(fptr) };
                 #debug("*fptr: %?", value);
                 objc::object_setInstanceVariable(mainobj, name, value)
             };

	     ret mainobj;
	 }
	 fn release(mainobj: id) {
             let sel = str::as_c_str("release") { |s|
                 objc::sel_registerName(s)
             };
             objc::objc_msgSend(mainobj, sel);
	 }
    }

    fn runmain(f: fn()) {
	let pool = NSAutoreleasePool::alloc();
	NSAutoreleasePool::init(pool);
        let NSApp = NSApplication::sharedApplication();

        let mainobj = MainObj::create(f);
	NSApp::setDelegate(NSApp, mainobj);
	NSApp::run(NSApp);

	MainObj::release(mainobj);
	NSAutoreleasePool::release(pool);
    }
}
<commit_msg>Update for task API changes<commit_after>export OSMain, Msg;

import azure::*;
import azure::bindgen::*;
import azure::cairo;
import azure::cairo::bindgen::*;
import comm::*;
import azure::cairo::cairo_surface_t;
import gfx::renderer::{Sink};

type OSMain = chan<Msg>;

enum Msg {
    BeginDrawing(chan<AzDrawTargetRef>),
    Draw(chan<AzDrawTargetRef>, AzDrawTargetRef),
    AddKeyHandler(chan<()>),
    Exit
}

fn OSMain() -> OSMain {
    on_osmain::<Msg> {|po|
        platform::runmain {||
            #debug("preparing to enter main loop");
	    mainloop(po);
        }
    }
}

fn mainloop(po: port<Msg>) {

    let mut key_handlers: [chan<()>] = [];

    sdl::init([
        sdl::init_video
    ]);

    let screen = sdl::video::set_video_mode(
        800, 600, 32,
        [sdl::video::swsurface],
        [sdl::video::doublebuf]);
    assert !ptr::is_null(screen);

    let surfaces = surface_set();

    loop {
        sdl::event::poll_event {|event|

            alt event {
              sdl::event::keydown_event(_) {
                key_handlers.iter {|key_ch|
                    key_ch.send(())
                }
              }
              _ { }
            }
        }

        // Handle messages
        if po.peek() {
            alt check po.recv() {
              AddKeyHandler(key_ch) {
                key_handlers += [key_ch];
              }
              BeginDrawing(sender) {
                lend_surface(surfaces, sender);
              }
              Draw(sender, dt) {
                return_surface(surfaces, dt);
                lend_surface(surfaces, sender);

                #debug("osmain: drawing to screen");
                assert surfaces.s1.surf.az_target == dt;
                let sdl_surf = surfaces.s1.surf.sdl_surf;

                cairo_surface_flush(surfaces.s1.surf.cairo_surf);
                sdl::video::unlock_surface(sdl_surf);
                sdl::video::blit_surface(sdl_surf, ptr::null(),
                                         screen, ptr::null());
                sdl::video::lock_surface(sdl_surf);
                sdl::video::flip(screen);
              }
              exit { break; }
            }
        }
    }
    destroy_surface(surfaces.s1.surf);
    destroy_surface(surfaces.s2.surf);
    sdl::quit();
}

#[doc = "
Implementation to allow the osmain channel to be used as a graphics
sink for the renderer
"]
impl OSMain of Sink for OSMain {
    fn begin_drawing(next_dt: chan<AzDrawTargetRef>) {
        self.send(BeginDrawing(next_dt))
    }
    fn draw(next_dt: chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef) {
        self.send(Draw(next_dt, draw_me))
    }
}

type surface_set = {
    mut s1: {
        surf: surface,
        have: bool
    },
    mut s2: {
        surf: surface,
        have: bool
    }
};

fn lend_surface(surfaces: surface_set, recvr: chan<AzDrawTargetRef>) {
    // We are in a position to lend out the surface?
    assert surfaces.s1.have;
    // Ok then take it
    let dt1 = surfaces.s1.surf.az_target;
    #debug("osmain: lending surface %?", dt1);
    recvr.send(dt1);
    // Now we don't have it
    surfaces.s1 = {
        have: false
        with surfaces.s1
    };
    // But we (hopefully) have another!
    surfaces.s1 <-> surfaces.s2;
    // Let's look
    assert surfaces.s1.have;
}

fn return_surface(surfaces: surface_set, dt: AzDrawTargetRef) {
    #debug("osmain: returning surface %?", dt);
    // We have room for a return
    assert surfaces.s1.have;
    assert !surfaces.s2.have;
    assert surfaces.s2.surf.az_target == dt;
    // Now we have it again
    surfaces.s2 = {
        have: true
        with surfaces.s2
    };
}

fn surface_set() -> surface_set {
    {
        mut s1: {
            surf: mk_surface(),
            have: true
        },
        mut s2: {
            surf: mk_surface(),
            have: true
        }
    }
}

type surface = {
    sdl_surf: *sdl::video::surface,
    cairo_surf: *cairo_surface_t,
    az_target: AzDrawTargetRef
};

fn mk_surface() -> surface {
    let sdl_surf = sdl::video::create_rgb_surface(
        [sdl::video::swsurface],
        800, 600, 32,
        0x00FF0000u32,
        0x0000FF00u32,
        0x000000FFu32,
        0x00000000u32
        );
    assert !ptr::is_null(sdl_surf);
    sdl::video::lock_surface(sdl_surf);
    let cairo_surf = unsafe {
        cairo_image_surface_create_for_data(
            unsafe::reinterpret_cast((*sdl_surf).pixels),
            cairo::CAIRO_FORMAT_RGB24,
            (*sdl_surf).w,
            (*sdl_surf).h,
            (*sdl_surf).pitch as libc::c_int
        )
    };
    assert !ptr::is_null(cairo_surf);

    let azure_target = AzCreateDrawTargetForCairoSurface(cairo_surf);
    assert !ptr::is_null(azure_target);

    {
        sdl_surf: sdl_surf,
        cairo_surf: cairo_surf,
        az_target: azure_target
    }
}

fn destroy_surface(surface: surface) {
    AzReleaseDrawTarget(surface.az_target);
    cairo_surface_destroy(surface.cairo_surf);
    sdl::video::unlock_surface(surface.sdl_surf);
    sdl::video::free_surface(surface.sdl_surf);
}

#[doc = "A function for spawning into the platform's main thread"]
fn on_osmain<T: send>(+f: fn~(comm::port<T>)) -> comm::chan<T> {
    let builder = task::builder();
    let opts = {
        sched: some({
            mode: task::osmain,
            foreign_stack_size: none
        })
        with task::get_opts(builder)
    };
    task::set_opts(builder, opts);
    ret task::run_listener(builder, f);
}

#[cfg(target_os = "linux")]
mod platform {
    fn runmain(f: fn()) {
        f()
    }
}

#[cfg(target_os = "macos")]
mod platform {
    use cocoa;
    import cocoa::base::*;

    mod NSApplication {
        fn sharedApplication() -> id {
            let klass = str::as_c_str("NSApplication") { |s|
                objc::objc_getClass(s)
            };

            let sel = str::as_c_str("sharedApplication") { |s|
                objc::sel_registerName(s)
            };

            let nsapp = objc::objc_msgSend(klass, sel);
            #debug("nsapp: %d", (nsapp as int));

	    ret nsapp;
        }
    }

    mod NSAutoreleasePool {
        fn alloc() -> id {
            let klass = str::as_c_str("NSAutoreleasePool") { |s|
                objc::objc_getClass(s)
            };
            let sel = str::as_c_str("alloc") { |s|
                objc::sel_registerName(s)
            };
            let pool = objc::objc_msgSend(klass, sel);
            #debug("autorelease pool: %?", pool);
            ret pool;
        }
        fn init(pool: id) {
            let sel = str::as_c_str("init") { |s|
                objc::sel_registerName(s)
            };
            objc::objc_msgSend(pool, sel);
        }
        fn release(pool: id) {
            let sel = str::as_c_str("release") { |s|
                objc::sel_registerName(s)
            };
            objc::objc_msgSend(pool, sel);
        }
    }

    mod NSApp {
         fn setDelegate(nsapp: id, main: id) {
	     #debug("NSApp::setDelegate");
	     let sel = str::as_c_str("setDelegate:") { |s|
	         objc::sel_registerName(s)
	     };
	     cocoa::msgSend1Id(nsapp, sel, main);
         }

         fn run(nsapp: id) {
	    #debug("NSApp::run");
            let sel = str::as_c_str("run") { |s|
                objc::sel_registerName(s)
            };
            objc::objc_msgSend(nsapp, sel);
         }
    }

    mod MainObj {
         crust fn applicationDidFinishLaunching(this: id, _sel: SEL) {
	     #debug("applicationDidFinishLaunching");

	     let fptr: *fn() = ptr::null();
	     str::as_c_str("fptr") { |name|
	         let outValue = unsafe { unsafe::reinterpret_cast(ptr::addr_of(fptr)) };
                 #debug("*fptr %?", outValue);
                 objc::object_getInstanceVariable(this, name, outValue)
             };

	     #debug("getting osmain fptr: %?", fptr);

	     unsafe {
	         // FIXME: We probably don't want to run the main routine in a crust function
                 (*fptr)();
             }
	 }

    	 fn create(f: fn()) -> id {
             let NSObject = str::as_c_str("NSObject") { |s|
	         objc::objc_getClass(s)
             };
	     let MainObj = str::as_c_str("MainObj") { |s|
	         objc::objc_allocateClassPair(NSObject, s, 0 as libc::size_t)
	     };

             // Add a field to our class to contain a pointer to a rust closure
	     let res = str::as_c_str("fptr") { |name|
                 str::as_c_str("^i") { |types|
                     objc::class_addIvar(MainObj, name,
                                         sys::size_of::<libc::uintptr_t>() as libc::size_t,
                                         16u8, types)
                 }
             };
 	     assert res == true;

	     let launchfn = str::as_c_str("applicationDidFinishLaunching:") { |s|
	         objc::sel_registerName(s)
	     };
	     let _ = str::as_c_str("@@:") { |types|
	         objc::class_addMethod(MainObj, launchfn, applicationDidFinishLaunching, types)
	     };

	     objc::objc_registerClassPair(MainObj);

             let sel = str::as_c_str("alloc") { |s|
                 objc::sel_registerName(s)
             };
             let mainobj = objc::objc_msgSend(MainObj, sel);

             let sel = str::as_c_str("init") { |s|
                 objc::sel_registerName(s)
             };
             objc::objc_msgSend(mainobj, sel);

	     let fptr = ptr::addr_of(f);
	     str::as_c_str("fptr") { |name|
	         #debug("setting osmain fptr: %?", fptr);
		 let value = unsafe { unsafe::reinterpret_cast(fptr) };
                 #debug("*fptr: %?", value);
                 objc::object_setInstanceVariable(mainobj, name, value)
             };

	     ret mainobj;
	 }
	 fn release(mainobj: id) {
             let sel = str::as_c_str("release") { |s|
                 objc::sel_registerName(s)
             };
             objc::objc_msgSend(mainobj, sel);
	 }
    }

    fn runmain(f: fn()) {
	let pool = NSAutoreleasePool::alloc();
	NSAutoreleasePool::init(pool);
        let NSApp = NSApplication::sharedApplication();

        let mainobj = MainObj::create(f);
	NSApp::setDelegate(NSApp, mainobj);
	NSApp::run(NSApp);

	MainObj::release(mainobj);
	NSAutoreleasePool::release(pool);
    }
}
<|endoftext|>


<commit_before><commit_msg>Started building handshakes test case for new API<commit_after>#[macro_use]
extern crate time_steward;

extern crate rand;
extern crate bincode;

extern crate serde;
#[macro_use]
extern crate serde_derive;

use time_steward::{DeterministicRandomId};
use time_steward::rowless::stewards::{simple_flat};
use simple_flat::{TimeSteward, ConstructibleTimeSteward, Event, DataTimelineHandle, automatic_tracking};
use simple_flat::Steward;
use automatic_tracking::{SimpleTimeline, ConstantTimeline};

type Time = i64;

const HOW_MANY_PHILOSOPHERS: i32 = 7;

type PhilosopherHandle = DataTimelineHandle <SimpleTimeline <Philosopher>>;

time_steward_basics!(struct Basics {
  type Time = Time;
  type GlobalTimeline = ConstantTimeline <[PhilosopherHandle; HOW_MANY_PHILOSOPHERS]>];
  type IncludedTypes = TimeStewardTypes;
});

#[derive (Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
struct Philosopher {
  // This is sometimes in the future because
  // they muse philosophically about handshakes
  // for a while, whenever one of them happens.
  time_when_next_initiates_handshake: Time,
  next_handshake_prediction: PredictionHandle <Shake>,
}
impl Column for Philosopher {
  type FieldType = Self;
  fn column_id() -> ColumnId {
    ColumnId(0x4084d1501468b6dd)
  }
}

fn change_next_handshake_time <Accessor: EventAccessor> (accessor: & Accessor, handle: & PhilosopherHandle, time: Time) {
  let philosopher = query_simple_timeline (accessor, handle, After).expect ("philosophers should never not exist");
  if let Some(prediction) = philosopher.next_handshake_prediction.take() {
    accessor.destroy_prediction (&prediction);
  }
  philosopher.time_when_next_initiates_handshake = time;
  if (time >= accessor.now().base) {
    philosopher.next_handshake_prediction = Some(accessor.create_prediction (time, Shake {whodunnit: handle.clone()}));
  }
  modify_simple_timeline (accessor, handle, Some (philosopher));
}

fn unchange_next_handshake_time <Accessor: EventAccessor> (accessor: & Accessor, handle: & PhilosopherHandle) {
  let philosopher = accessor.query (handle, GetValue, After).expect ("philosophers should never not exist");
  if let Some(prediction) = philosopher.next_handshake_prediction.take() {
    accessor.destroy_prediction (&prediction);
  }
  let philosopher = accessor.query (handle, GetValue, Before).expect ("philosophers should never not exist");
  if let Some(prediction) = philosopher.next_handshake_prediction.take() {
    accessor.undestroy_prediction (&prediction, None);
  }
  unmodify_simple_timeline (accessor, handle);
}

type TimeStewardTypes = (ListedType<SimpleTimeline <Philosopher>>,
                         ListedType<Initialize>,
                         ListedType<Tweak>,
                         ListedType<TweakUnsafe>,
                         ListedType<Shake>);

fn display_snapshot<S: time_steward::Snapshot<Basics = Basics>>(snapshot: &S) {
  println!("snapshot for {}", snapshot.now());
  for handle in snapshot.query (snapshot.global_timeline(), GetValue, After).iter() {
    println!("{}",
             snapshot.query(handle, GetValue, After)
               .expect("missing philosopher")
               .time_when_next_initiates_handshake);
  }
}

time_steward_predictor! (
  struct Shaker, Basics, PredictorId(0x0e7f27c7643f8167), watching Philosopher,
  | pa, whodunnit | {
// println!("Planning {}", whodunnit);
  let me = pa.get::<Philosopher>(whodunnit).unwrap().clone();
  pa.predict_at_time(me.time_when_next_initiates_handshake, Shake::new (whodunnit));
});

time_steward_event! (
  struct Shake {whodunnit: RowId}, Basics, EventId (0x8987a0b8e7d3d624),
  fn execute <Accessor: EventAccessor <Steward = Self::Steward, Event = Self>> (&self, accessor: & Accessor) {
    let now = *accessor.now();
    let friend_id = accessor.gen_range(0, HOW_MANY_PHILOSOPHERS);
    let awaken_time_1 = now + accessor.gen_range(-1, 4);
    let awaken_time_2 = now + accessor.gen_range(-1, 7);
    let philosophers = accessor.query (snapshot.global_timeline(), GetValue, After);
// println!("SHAKE!!! @{}. {}={}; {}={}", now, self.whodunnit, awaken_time_2, friend_id, awaken_time_1);
// IF YOU SHAKE YOUR OWN HAND YOU RECOVER
// IN THE SECOND TIME APPARENTLY
    change_next_handshake_time (accessor, philosophers [friend_id], awaken_time_1);
    change_next_handshake_time (accessor, self.whodunnit, awaken_time_2);
  }
  fn undo <Accessor: EventAccessor <Steward = Self::Steward, Event = Self>> (&self, accessor: & Accessor) {
    let friend_id = accessor.gen_range(0, HOW_MANY_PHILOSOPHERS);
    unchange_next_handshake_time (accessor, philosophers [friend_id]);
    unchange_next_handshake_time (accessor, self.whodunnit);
  }
);

time_steward_event! (
  struct Initialize {}, Basics, EventId (0xd5e73d8ba6ec59a2),
  | &self, m | {
    println!("FIAT!!!!!");
    for i in 0..HOW_MANY_PHILOSOPHERS {
      m.set::<Philosopher>(get_philosopher_id(i),
        Some(Philosopher {
          time_when_next_initiates_handshake: (i + 1) as Time,
        })
      );
    }
  }
);

time_steward_event! (
  struct Tweak {}, Basics, EventId (0xfe9ff3047f9a9552),
  | &self, accessor | {
    println!(" Tweak !!!!!");
    let now = *accessor.now();
    let friend_id = accessor.gen_range(0, HOW_MANY_PHILOSOPHERS);
    let awaken_time = now + accessor.gen_range(-1, 7);
    let philosophers = accessor.query (snapshot.global_timeline(), GetValue, After);
    change_next_handshake_time (accessor, philosophers [friend_id], awaken_time);
  }
);

use rand::{Rng, SeedableRng, ChaChaRng};
thread_local! {static INCONSISTENT: u32 = rand::thread_rng().gen::<u32>();}

time_steward_event! (
  struct TweakUnsafe {}, Basics, EventId (0xa1618440808703da),
  | &self, m | {
    let now = *accessor.now();
    let friend_id = accessor.gen_range(0, HOW_MANY_PHILOSOPHERS);
    let philosophers = accessor.query (snapshot.global_timeline(), GetValue, After);

    let inconsistent = INCONSISTENT.with (| value | {
      *value
    });
    let mut rng = ChaChaRng::from_seed (& [inconsistent, accessor.next_u32()]);
    let awaken_time = now + rng.gen_range(-1, 7);

    change_next_handshake_time (accessor, philosophers [friend_id], awaken_time);
  }
);

#[test]
pub fn handshakes_simple() {
  type Steward = crossverified::Steward<Basics, inefficient_flat::Steward<Basics>, memoized_flat::Steward<Basics>>;
  let mut stew: Steward = Steward::from_constants(());

  stew.insert_fiat_event(0,
                       DeterministicRandomId::new(&0x32e1570766e768a7u64),
                       Initialize::new())
    .unwrap();

  for increment in 1..21 {
    let snapshot: <Steward as TimeSteward>::Snapshot = stew.snapshot_before(&(increment * 100i64)).unwrap();
    display_snapshot(&snapshot);
  }
}

#[test]
pub fn handshakes_reloading() {
  type Steward = crossverified::Steward<Basics, amortized::Steward<Basics>, memoized_flat::Steward<Basics>>;
  let mut stew: Steward = Steward::from_constants(());

  stew.insert_fiat_event(0,
                       DeterministicRandomId::new(&0x32e1570766e768a7u64),
                       Initialize::new())
    .unwrap();

  let mut snapshots = Vec::new();
  for increment in 1..21 {
    snapshots.push(stew.snapshot_before(&(increment * 100i64)));
    stew = Steward::from_snapshot::<<Steward as TimeSteward>::Snapshot> (snapshots.last().unwrap().as_ref().unwrap());
  }
  for snapshot in snapshots.iter_mut()
    .map(|option| option.as_mut().expect("all these snapshots should have been valid")) {
    display_snapshot(snapshot);
    let mut writer: Vec<u8> = Vec::with_capacity(128);
    time_steward::serialize_snapshot:: <Basics, <Steward as TimeSteward>::Snapshot,_,_> (snapshot, &mut writer, bincode::Infinite).unwrap();
    // let serialized = String::from_utf8 (serializer.into_inner()).unwrap();
    println!("{:?}", writer);
    use std::io::Cursor;
    let mut reader = Cursor::new(writer);
    let deserialized = time_steward::deserialize_snapshot:: <Basics, _,_> (&mut reader, bincode::Infinite/*serialized.as_bytes().iter().map (| bite | Ok (bite.clone()))*/).unwrap();
    println!("{:?}", deserialized);
    display_snapshot(&deserialized);
    use time_steward::MomentaryAccessor;
    display_snapshot(&Steward::from_snapshot::<time_steward::FiatSnapshot<Basics>>(&deserialized).snapshot_before(deserialized.now()).unwrap());
  }
  // panic!("anyway")
}

#[test]
fn handshakes_retroactive() {
  type Steward = crossverified::Steward<Basics, amortized::Steward<Basics>, flat_to_inefficient_full::Steward<Basics, memoized_flat::Steward <Basics> >>;
  let mut stew: Steward = Steward::from_constants(());

  stew.insert_fiat_event(0,
                       DeterministicRandomId::new(&0x32e1570766e768a7u64),
                       Initialize::new())
    .unwrap();

  stew.snapshot_before(&(2000i64));
  for increment in 1..21 {
    stew.insert_fiat_event(increment * 100i64, DeterministicRandomId::new(&increment), Tweak::new()).unwrap();
    let snapshot: <Steward as TimeSteward>::Snapshot = stew.snapshot_before(&(2000i64)).unwrap();
    display_snapshot(&snapshot);
  }

}

#[test]
fn local_synchronization_test() {
  use time_steward::stewards::simply_synchronized;
  use std::net::{TcpListener, TcpStream};
  use std::io::{BufReader, BufWriter};
  let listener = TcpListener::bind(("127.0.0.1", 0)).unwrap();
  let port = listener.local_addr().unwrap().port();
  ::std::thread::spawn(move || {
    let end_0 = listener.accept().unwrap().0;
    let mut stew_0: simply_synchronized::Steward<Basics, amortized::Steward<Basics>> =
      simply_synchronized::Steward::new(DeterministicRandomId::new(&0u32),
                                        0,
                                        4,
                                        (),
                                        BufReader::new(end_0.try_clone().unwrap()),
                                        BufWriter::new(end_0));
    stew_0.insert_fiat_event(0,
                         DeterministicRandomId::new(&0x32e1570766e768a7u64),
                         Initialize::new())
      .unwrap();

    for increment in 1..21 {
      let time = increment * 100i64;
      if increment % 3 == 0 {
        stew_0.insert_fiat_event(time, DeterministicRandomId::new(&increment), Tweak::new())
          .unwrap();
      }
      stew_0.snapshot_before(&time);
      stew_0.settle_before(time);
    }
    stew_0.finish();
  });
  let end_1 = TcpStream::connect(("127.0.0.1", port)).unwrap();
  let mut stew_1: simply_synchronized::Steward<Basics, amortized::Steward<Basics>> =
    simply_synchronized::Steward::new(DeterministicRandomId::new(&1u32),
                                      0,
                                      4,
                                      (),
                                      BufReader::new(end_1.try_clone().unwrap()),
                                      BufWriter::new(end_1));

  for increment in 1..21 {
    let time = increment * 100i64;
    if increment % 4 == 0 {
      stew_1.insert_fiat_event(time, DeterministicRandomId::new(&increment), Tweak::new()).unwrap();
    }
    stew_1.snapshot_before(&time);
    stew_1.settle_before(time);
  }
  stew_1.finish();
}

#[test]
#[should_panic (expected = "event occurred this way locally")]
fn local_synchronization_failure() {
  use time_steward::stewards::simply_synchronized;
  use std::net::{TcpListener, TcpStream};
  use std::io::{BufReader, BufWriter};
  let listener = TcpListener::bind(("127.0.0.1", 0)).unwrap();
  let port = listener.local_addr().unwrap().port();
  ::std::thread::spawn(move || {
    let end_0 = listener.accept().unwrap().0;
    let mut stew_0: simply_synchronized::Steward<Basics, amortized::Steward<Basics>> =
      simply_synchronized::Steward::new(DeterministicRandomId::new(&0u32),
                                        0,
                                        4,
                                        (),
                                        BufReader::new(end_0.try_clone().unwrap()),
                                        BufWriter::new(end_0));
    stew_0.insert_fiat_event(0,
                         DeterministicRandomId::new(&0x32e1570766e768a7u64),
                         Initialize::new())
      .unwrap();

    for increment in 1..21 {
      let time = increment * 100i64;
      if increment % 3 == 0 {
        stew_0.insert_fiat_event(time,
                             DeterministicRandomId::new(&increment),
                             TweakUnsafe::new())
          .unwrap();
      }
      stew_0.snapshot_before(&time);
      stew_0.settle_before(time);
    }
    stew_0.finish();
  });
  let end_1 = TcpStream::connect(("127.0.0.1", port)).unwrap();
  let mut stew_1: simply_synchronized::Steward<Basics, amortized::Steward<Basics>> =
    simply_synchronized::Steward::new(DeterministicRandomId::new(&1u32),
                                      0,
                                      4,
                                      (),
                                      BufReader::new(end_1.try_clone().unwrap()),
                                      BufWriter::new(end_1));

  for increment in 1..21 {
    let time = increment * 100i64;
    if increment % 4 == 0 {
      stew_1.insert_fiat_event(time,
                           DeterministicRandomId::new(&increment),
                           TweakUnsafe::new())
        .unwrap();
    }
    stew_1.snapshot_before(&time);
    stew_1.settle_before(time);
  }
  stew_1.finish();
}
<|endoftext|>


<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! A module for working with borrowed data.
//!
//! # The `BorrowFrom` traits
//!
//! In general, there may be several ways to "borrow" a piece of data.  The
//! typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T`
//! (a mutable borrow). But types like `Vec<T>` provide additional kinds of
//! borrows: the borrowed slices `&[T]` and `&mut [T]`.
//!
//! When writing generic code, it is often desirable to abstract over all ways
//! of borrowing data from a given type. That is the role of the `BorrowFrom`
//! trait: if `T: BorrowFrom<U>`, then `&T` can be borrowed from `&U`.  A given
//! type can be borrowed as multiple different types. In particular, `Vec<T>:
//! BorrowFrom<Vec<T>>` and `[T]: BorrowFrom<Vec<T>>`.
//!
//! # The `ToOwned` trait
//!
//! Some types make it possible to go from borrowed to owned, usually by
//! implementing the `Clone` trait. But `Clone` works only for going from `&T`
//! to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data
//! from any borrow of a given type.
//!
//! # The `Cow` (clone-on-write) type
//!
//! The type `Cow` is a smart pointer providing clone-on-write functionality: it
//! can enclose and provide immutable access to borrowed data, and clone the
//! data lazily when mutation or ownership is required. The type is designed to
//! work with general borrowed data via the `BorrowFrom` trait.
//!
//! `Cow` implements both `Deref`, which means that you can call
//! non-mutating methods directly on the data it encloses. If mutation
//! is desired, `to_mut` will obtain a mutable references to an owned
//! value, cloning if necessary.

#![unstable = "recently added as part of collections reform"]

use clone::Clone;
use cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
use fmt;
use kinds::Sized;
use ops::Deref;
use option::Option;
use self::Cow::*;

/// A trait for borrowing data.
pub trait BorrowFrom<Sized? Owned> for Sized? {
    /// Immutably borrow from an owned value.
    fn borrow_from(owned: &Owned) -> &Self;
}

/// A trait for mutably borrowing data.
pub trait BorrowFromMut<Sized? Owned> for Sized? : BorrowFrom<Owned> {
    /// Mutably borrow from an owned value.
    fn borrow_from_mut(owned: &mut Owned) -> &mut Self;
}

impl<Sized? T> BorrowFrom<T> for T {
    fn borrow_from(owned: &T) -> &T { owned }
}

impl<Sized? T> BorrowFromMut<T> for T {
    fn borrow_from_mut(owned: &mut T) -> &mut T { owned }
}

impl<'a, Sized? T> BorrowFrom<&'a T> for T {
    fn borrow_from<'b>(owned: &'b &'a T) -> &'b T { &**owned }
}

impl<'a, Sized? T> BorrowFrom<&'a mut T> for T {
    fn borrow_from<'b>(owned: &'b &'a mut T) -> &'b T { &**owned }
}

impl<'a, Sized? T> BorrowFromMut<&'a mut T> for T {
    fn borrow_from_mut<'b>(owned: &'b mut &'a mut T) -> &'b mut T { &mut **owned }
}

impl<'a, T, Sized? B> BorrowFrom<Cow<'a, T, B>> for B where B: ToOwned<T> {
    fn borrow_from<'b>(owned: &'b Cow<'a, T, B>) -> &'b B {
        &**owned
    }
}

/// Trait for moving into a `Cow`
pub trait IntoCow<'a, T, Sized? B> {
    /// Moves `self` into `Cow`
    fn into_cow(self) -> Cow<'a, T, B>;
}

impl<'a, T, Sized? B> IntoCow<'a, T, B> for Cow<'a, T, B> where B: ToOwned<T> {
    fn into_cow(self) -> Cow<'a, T, B> {
        self
    }
}

/// A generalization of Clone to borrowed data.
pub trait ToOwned<Owned> for Sized?: BorrowFrom<Owned> {
    /// Create owned data from borrowed data, usually by copying.
    fn to_owned(&self) -> Owned;
}

impl<T> ToOwned<T> for T where T: Clone {
    fn to_owned(&self) -> T { self.clone() }
}

/// A clone-on-write smart pointer.
///
/// # Example
///
/// ```rust
/// use std::borrow::Cow;
///
/// fn abs_all(input: &mut Cow<Vec<int>, [int]>) {
///     for i in range(0, input.len()) {
///         let v = input[i];
///         if v < 0 {
///             // clones into a vector the first time (if not already owned)
///             input.to_mut()[i] = -v;
///         }
///     }
/// }
/// ```
pub enum Cow<'a, T, Sized? B: 'a> where B: ToOwned<T> {
    /// Borrowed data.
    Borrowed(&'a B),

    /// Owned data.
    Owned(T)
}

impl<'a, T, Sized? B> Cow<'a, T, B> where B: ToOwned<T> {
    /// Acquire a mutable reference to the owned form of the data.
    ///
    /// Copies the data if it is not already owned.
    pub fn to_mut(&mut self) -> &mut T {
        match *self {
            Borrowed(borrowed) => {
                *self = Owned(borrowed.to_owned());
                self.to_mut()
            }
            Owned(ref mut owned) => owned
        }
    }

    /// Extract the owned data.
    ///
    /// Copies the data if it is not already owned.
    pub fn into_owned(self) -> T {
        match self {
            Borrowed(borrowed) => borrowed.to_owned(),
            Owned(owned) => owned
        }
    }

    /// Returns true if this `Cow` wraps a borrowed value
    pub fn is_borrowed(&self) -> bool {
        match *self {
            Borrowed(_) => true,
            _ => false,
        }
    }

    /// Returns true if this `Cow` wraps an owned value
    pub fn is_owned(&self) -> bool {
        match *self {
            Owned(_) => true,
            _ => false,
        }
    }
}

impl<'a, T, Sized? B> Deref<B> for Cow<'a, T, B> where B: ToOwned<T>  {
    fn deref(&self) -> &B {
        match *self {
            Borrowed(borrowed) => borrowed,
            Owned(ref owned) => BorrowFrom::borrow_from(owned)
        }
    }
}

impl<'a, T, Sized? B> Eq for Cow<'a, T, B> where B: Eq + ToOwned<T> {}

impl<'a, T, Sized? B> Ord for Cow<'a, T, B> where B: Ord + ToOwned<T> {
    #[inline]
    fn cmp(&self, other: &Cow<'a, T, B>) -> Ordering {
        Ord::cmp(&**self, &**other)
    }
}

impl<'a, T, Sized? B> PartialEq for Cow<'a, T, B> where B: PartialEq + ToOwned<T> {
    #[inline]
    fn eq(&self, other: &Cow<'a, T, B>) -> bool {
        PartialEq::eq(&**self, &**other)
    }
}

impl<'a, T, Sized? B> PartialOrd for Cow<'a, T, B> where B: PartialOrd + ToOwned<T> {
    #[inline]
    fn partial_cmp(&self, other: &Cow<'a, T, B>) -> Option<Ordering> {
        PartialOrd::partial_cmp(&**self, &**other)
    }
}

impl<'a, T, Sized? B> fmt::Show for Cow<'a, T, B> where B: fmt::Show + ToOwned<T>, T: fmt::Show {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Borrowed(ref b) => fmt::Show::fmt(b, f),
            Owned(ref o) => fmt::Show::fmt(o, f),
        }
    }
}
<commit_msg>impl Clone for Cow<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! A module for working with borrowed data.
//!
//! # The `BorrowFrom` traits
//!
//! In general, there may be several ways to "borrow" a piece of data.  The
//! typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T`
//! (a mutable borrow). But types like `Vec<T>` provide additional kinds of
//! borrows: the borrowed slices `&[T]` and `&mut [T]`.
//!
//! When writing generic code, it is often desirable to abstract over all ways
//! of borrowing data from a given type. That is the role of the `BorrowFrom`
//! trait: if `T: BorrowFrom<U>`, then `&T` can be borrowed from `&U`.  A given
//! type can be borrowed as multiple different types. In particular, `Vec<T>:
//! BorrowFrom<Vec<T>>` and `[T]: BorrowFrom<Vec<T>>`.
//!
//! # The `ToOwned` trait
//!
//! Some types make it possible to go from borrowed to owned, usually by
//! implementing the `Clone` trait. But `Clone` works only for going from `&T`
//! to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data
//! from any borrow of a given type.
//!
//! # The `Cow` (clone-on-write) type
//!
//! The type `Cow` is a smart pointer providing clone-on-write functionality: it
//! can enclose and provide immutable access to borrowed data, and clone the
//! data lazily when mutation or ownership is required. The type is designed to
//! work with general borrowed data via the `BorrowFrom` trait.
//!
//! `Cow` implements both `Deref`, which means that you can call
//! non-mutating methods directly on the data it encloses. If mutation
//! is desired, `to_mut` will obtain a mutable references to an owned
//! value, cloning if necessary.

#![unstable = "recently added as part of collections reform"]

use clone::Clone;
use cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
use fmt;
use kinds::Sized;
use ops::Deref;
use option::Option;
use self::Cow::*;

/// A trait for borrowing data.
pub trait BorrowFrom<Sized? Owned> for Sized? {
    /// Immutably borrow from an owned value.
    fn borrow_from(owned: &Owned) -> &Self;
}

/// A trait for mutably borrowing data.
pub trait BorrowFromMut<Sized? Owned> for Sized? : BorrowFrom<Owned> {
    /// Mutably borrow from an owned value.
    fn borrow_from_mut(owned: &mut Owned) -> &mut Self;
}

impl<Sized? T> BorrowFrom<T> for T {
    fn borrow_from(owned: &T) -> &T { owned }
}

impl<Sized? T> BorrowFromMut<T> for T {
    fn borrow_from_mut(owned: &mut T) -> &mut T { owned }
}

impl<'a, Sized? T> BorrowFrom<&'a T> for T {
    fn borrow_from<'b>(owned: &'b &'a T) -> &'b T { &**owned }
}

impl<'a, Sized? T> BorrowFrom<&'a mut T> for T {
    fn borrow_from<'b>(owned: &'b &'a mut T) -> &'b T { &**owned }
}

impl<'a, Sized? T> BorrowFromMut<&'a mut T> for T {
    fn borrow_from_mut<'b>(owned: &'b mut &'a mut T) -> &'b mut T { &mut **owned }
}

impl<'a, T, Sized? B> BorrowFrom<Cow<'a, T, B>> for B where B: ToOwned<T> {
    fn borrow_from<'b>(owned: &'b Cow<'a, T, B>) -> &'b B {
        &**owned
    }
}

/// Trait for moving into a `Cow`
pub trait IntoCow<'a, T, Sized? B> {
    /// Moves `self` into `Cow`
    fn into_cow(self) -> Cow<'a, T, B>;
}

impl<'a, T, Sized? B> IntoCow<'a, T, B> for Cow<'a, T, B> where B: ToOwned<T> {
    fn into_cow(self) -> Cow<'a, T, B> {
        self
    }
}

/// A generalization of Clone to borrowed data.
pub trait ToOwned<Owned> for Sized?: BorrowFrom<Owned> {
    /// Create owned data from borrowed data, usually by copying.
    fn to_owned(&self) -> Owned;
}

impl<T> ToOwned<T> for T where T: Clone {
    fn to_owned(&self) -> T { self.clone() }
}

/// A clone-on-write smart pointer.
///
/// # Example
///
/// ```rust
/// use std::borrow::Cow;
///
/// fn abs_all(input: &mut Cow<Vec<int>, [int]>) {
///     for i in range(0, input.len()) {
///         let v = input[i];
///         if v < 0 {
///             // clones into a vector the first time (if not already owned)
///             input.to_mut()[i] = -v;
///         }
///     }
/// }
/// ```
pub enum Cow<'a, T, Sized? B: 'a> where B: ToOwned<T> {
    /// Borrowed data.
    Borrowed(&'a B),

    /// Owned data.
    Owned(T)
}

impl<'a, T, Sized? B> Clone for Cow<'a, T, B> where B: ToOwned<T> {
    fn clone(&self) -> Cow<'a, T, B> {
        match *self {
            Borrowed(b) => Borrowed(b),
            Owned(ref o) => {
                let b: &B = BorrowFrom::borrow_from(o);
                Owned(b.to_owned())
            },
        }
    }
}

impl<'a, T, Sized? B> Cow<'a, T, B> where B: ToOwned<T> {
    /// Acquire a mutable reference to the owned form of the data.
    ///
    /// Copies the data if it is not already owned.
    pub fn to_mut(&mut self) -> &mut T {
        match *self {
            Borrowed(borrowed) => {
                *self = Owned(borrowed.to_owned());
                self.to_mut()
            }
            Owned(ref mut owned) => owned
        }
    }

    /// Extract the owned data.
    ///
    /// Copies the data if it is not already owned.
    pub fn into_owned(self) -> T {
        match self {
            Borrowed(borrowed) => borrowed.to_owned(),
            Owned(owned) => owned
        }
    }

    /// Returns true if this `Cow` wraps a borrowed value
    pub fn is_borrowed(&self) -> bool {
        match *self {
            Borrowed(_) => true,
            _ => false,
        }
    }

    /// Returns true if this `Cow` wraps an owned value
    pub fn is_owned(&self) -> bool {
        match *self {
            Owned(_) => true,
            _ => false,
        }
    }
}

impl<'a, T, Sized? B> Deref<B> for Cow<'a, T, B> where B: ToOwned<T>  {
    fn deref(&self) -> &B {
        match *self {
            Borrowed(borrowed) => borrowed,
            Owned(ref owned) => BorrowFrom::borrow_from(owned)
        }
    }
}

impl<'a, T, Sized? B> Eq for Cow<'a, T, B> where B: Eq + ToOwned<T> {}

impl<'a, T, Sized? B> Ord for Cow<'a, T, B> where B: Ord + ToOwned<T> {
    #[inline]
    fn cmp(&self, other: &Cow<'a, T, B>) -> Ordering {
        Ord::cmp(&**self, &**other)
    }
}

impl<'a, T, Sized? B> PartialEq for Cow<'a, T, B> where B: PartialEq + ToOwned<T> {
    #[inline]
    fn eq(&self, other: &Cow<'a, T, B>) -> bool {
        PartialEq::eq(&**self, &**other)
    }
}

impl<'a, T, Sized? B> PartialOrd for Cow<'a, T, B> where B: PartialOrd + ToOwned<T> {
    #[inline]
    fn partial_cmp(&self, other: &Cow<'a, T, B>) -> Option<Ordering> {
        PartialOrd::partial_cmp(&**self, &**other)
    }
}

impl<'a, T, Sized? B> fmt::Show for Cow<'a, T, B> where B: fmt::Show + ToOwned<T>, T: fmt::Show {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Borrowed(ref b) => fmt::Show::fmt(b, f),
            Owned(ref o) => fmt::Show::fmt(o, f),
        }
    }
}
<|endoftext|>


<commit_before>//! A type representing either success or failure

import either::Either;

/// The result type
enum result<T, U> {
    /// Contains the successful result value
    ok(T),
    /// Contains the error value
    err(U)
}

/**
 * Get the value out of a successful result
 *
 * # Failure
 *
 * If the result is an error
 */
pure fn get<T: copy, U>(res: result<T, U>) -> T {
    match res {
      ok(t) => t,
      err(the_err) => unchecked {
        fail fmt!("get called on error result: %?", the_err)
      }
    }
}

/**
 * Get the value out of an error result
 *
 * # Failure
 *
 * If the result is not an error
 */
pure fn get_err<T, U: copy>(res: result<T, U>) -> U {
    match res {
      err(u) => u,
      ok(_) => fail ~"get_error called on ok result"
    }
}

/// Returns true if the result is `ok`
pure fn is_ok<T, U>(res: result<T, U>) -> bool {
    match res {
      ok(_) => true,
      err(_) => false
    }
}

/// Returns true if the result is `err`
pure fn is_err<T, U>(res: result<T, U>) -> bool {
    !is_ok(res)
}

/**
 * Convert to the `either` type
 *
 * `ok` result variants are converted to `either::right` variants, `err`
 * result variants are converted to `either::left`.
 */
pure fn to_either<T: copy, U: copy>(res: result<U, T>) -> Either<T, U> {
    match res {
      ok(res) => either::Right(res),
      err(fail_) => either::Left(fail_)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `ok` then the value is extracted and passed to `op` whereupon
 * `op`s result is returned. if `res` is `err` then it is immediately
 * returned. This function can be used to compose the results of two
 * functions.
 *
 * Example:
 *
 *     let res = chain(read_file(file)) { |buf|
 *         ok(parse_buf(buf))
 *     }
 */
fn chain<T, U: copy, V: copy>(res: result<T, V>, op: fn(T) -> result<U, V>)
    -> result<U, V> {
    match res {
      ok(t) => op(t),
      err(e) => err(e)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `err` then the value is extracted and passed to `op`
 * whereupon `op`s result is returned. if `res` is `ok` then it is
 * immediately returned.  This function can be used to pass through a
 * successful result while handling an error.
 */
fn chain_err<T: copy, U: copy, V: copy>(
    res: result<T, V>,
    op: fn(V) -> result<T, U>)
    -> result<T, U> {
    match res {
      ok(t) => ok(t),
      err(v) => op(v)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `ok` then the value is extracted and passed to `op` whereupon
 * `op`s result is returned. if `res` is `err` then it is immediately
 * returned. This function can be used to compose the results of two
 * functions.
 *
 * Example:
 *
 *     iter(read_file(file)) { |buf|
 *         print_buf(buf)
 *     }
 */
fn iter<T, E>(res: result<T, E>, f: fn(T)) {
    match res {
      ok(t) => f(t),
      err(_) => ()
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `err` then the value is extracted and passed to `op` whereupon
 * `op`s result is returned. if `res` is `ok` then it is immediately returned.
 * This function can be used to pass through a successful result while
 * handling an error.
 */
fn iter_err<T, E>(res: result<T, E>, f: fn(E)) {
    match res {
      ok(_) => (),
      err(e) => f(e)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `ok` then the value is extracted and passed to `op` whereupon
 * `op`s result is wrapped in `ok` and returned. if `res` is `err` then it is
 * immediately returned.  This function can be used to compose the results of
 * two functions.
 *
 * Example:
 *
 *     let res = map(read_file(file)) { |buf|
 *         parse_buf(buf)
 *     }
 */
fn map<T, E: copy, U: copy>(res: result<T, E>, op: fn(T) -> U)
  -> result<U, E> {
    match res {
      ok(t) => ok(op(t)),
      err(e) => err(e)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `err` then the value is extracted and passed to `op` whereupon
 * `op`s result is wrapped in an `err` and returned. if `res` is `ok` then it
 * is immediately returned.  This function can be used to pass through a
 * successful result while handling an error.
 */
fn map_err<T: copy, E, F: copy>(res: result<T, E>, op: fn(E) -> F)
  -> result<T, F> {
    match res {
      ok(t) => ok(t),
      err(e) => err(op(e))
    }
}

impl<T, E> result<T, E> {
    fn is_ok() -> bool { is_ok(self) }

    fn is_err() -> bool { is_err(self) }

    fn iter(f: fn(T)) {
        match self {
          ok(t) => f(t),
          err(_) => ()
        }
    }

    fn iter_err(f: fn(E)) {
        match self {
          ok(_) => (),
          err(e) => f(e)
        }
    }
}

impl<T: copy, E> result<T, E> {
    fn get() -> T { get(self) }

    fn map_err<F:copy>(op: fn(E) -> F) -> result<T,F> {
        match self {
          ok(t) => ok(t),
          err(e) => err(op(e))
        }
    }
}

impl<T, E: copy> result<T, E> {
    fn get_err() -> E { get_err(self) }

    fn map<U:copy>(op: fn(T) -> U) -> result<U,E> {
        match self {
          ok(t) => ok(op(t)),
          err(e) => err(e)
        }
    }
}

impl<T: copy, E: copy> result<T, E> {
    fn chain<U:copy>(op: fn(T) -> result<U,E>) -> result<U,E> {
        chain(self, op)
    }

    fn chain_err<F:copy>(op: fn(E) -> result<T,F>) -> result<T,F> {
        chain_err(self, op)
    }
}

/**
 * Maps each element in the vector `ts` using the operation `op`.  Should an
 * error occur, no further mappings are performed and the error is returned.
 * Should no error occur, a vector containing the result of each map is
 * returned.
 *
 * Here is an example which increments every integer in a vector,
 * checking for overflow:
 *
 *     fn inc_conditionally(x: uint) -> result<uint,str> {
 *         if x == uint::max_value { return err("overflow"); }
 *         else { return ok(x+1u); }
 *     }
 *     map(~[1u, 2u, 3u], inc_conditionally).chain {|incd|
 *         assert incd == ~[2u, 3u, 4u];
 *     }
 */
fn map_vec<T,U:copy,V:copy>(
    ts: &[T], op: fn(T) -> result<V,U>) -> result<~[V],U> {

    let mut vs: ~[V] = ~[];
    vec::reserve(vs, vec::len(ts));
    for vec::each(ts) |t| {
        match op(t) {
          ok(v) => vec::push(vs, v),
          err(u) => return err(u)
        }
    }
    return ok(vs);
}

fn map_opt<T,U:copy,V:copy>(
    o_t: option<T>, op: fn(T) -> result<V,U>) -> result<option<V>,U> {

    match o_t {
      none => ok(none),
      some(t) => match op(t) {
        ok(v) => ok(some(v)),
        err(e) => err(e)
      }
    }
}

/**
 * Same as map, but it operates over two parallel vectors.
 *
 * A precondition is used here to ensure that the vectors are the same
 * length.  While we do not often use preconditions in the standard
 * library, a precondition is used here because result::t is generally
 * used in 'careful' code contexts where it is both appropriate and easy
 * to accommodate an error like the vectors being of different lengths.
 */
fn map_vec2<S,T,U:copy,V:copy>(ss: &[S], ts: &[T],
                               op: fn(S,T) -> result<V,U>) -> result<~[V],U> {

    assert vec::same_length(ss, ts);
    let n = vec::len(ts);
    let mut vs = ~[];
    vec::reserve(vs, n);
    let mut i = 0u;
    while i < n {
        match op(ss[i],ts[i]) {
          ok(v) => vec::push(vs, v),
          err(u) => return err(u)
        }
        i += 1u;
    }
    return ok(vs);
}

/**
 * Applies op to the pairwise elements from `ss` and `ts`, aborting on
 * error.  This could be implemented using `map2()` but it is more efficient
 * on its own as no result vector is built.
 */
fn iter_vec2<S,T,U:copy>(ss: &[S], ts: &[T],
                         op: fn(S,T) -> result<(),U>) -> result<(),U> {

    assert vec::same_length(ss, ts);
    let n = vec::len(ts);
    let mut i = 0u;
    while i < n {
        match op(ss[i],ts[i]) {
          ok(()) => (),
          err(u) => return err(u)
        }
        i += 1u;
    }
    return ok(());
}

/// Unwraps a result, assuming it is an `ok(T)`
fn unwrap<T, U>(-res: result<T, U>) -> T {
    unsafe {
        let addr = match res {
          ok(x) => ptr::addr_of(x),
          err(_) => fail ~"error result"
        };
        let liberated_value = unsafe::reinterpret_cast(*addr);
        unsafe::forget(res);
        return liberated_value;
    }
}

#[cfg(test)]
mod tests {
    fn op1() -> result::result<int, ~str> { result::ok(666) }

    fn op2(&&i: int) -> result::result<uint, ~str> {
        result::ok(i as uint + 1u)
    }

    fn op3() -> result::result<int, ~str> { result::err(~"sadface") }

    #[test]
    fn chain_success() {
        assert get(chain(op1(), op2)) == 667u;
    }

    #[test]
    fn chain_failure() {
        assert get_err(chain(op3(), op2)) == ~"sadface";
    }

    #[test]
    fn test_impl_iter() {
        let mut valid = false;
        ok::<~str, ~str>(~"a").iter(|_x| valid = true);
        assert valid;

        err::<~str, ~str>(~"b").iter(|_x| valid = false);
        assert valid;
    }

    #[test]
    fn test_impl_iter_err() {
        let mut valid = true;
        ok::<~str, ~str>(~"a").iter_err(|_x| valid = false);
        assert valid;

        valid = false;
        err::<~str, ~str>(~"b").iter_err(|_x| valid = true);
        assert valid;
    }

    #[test]
    fn test_impl_map() {
        assert ok::<~str, ~str>(~"a").map(|_x| ~"b") == ok(~"b");
        assert err::<~str, ~str>(~"a").map(|_x| ~"b") == err(~"a");
    }

    #[test]
    fn test_impl_map_err() {
        assert ok::<~str, ~str>(~"a").map_err(|_x| ~"b") == ok(~"a");
        assert err::<~str, ~str>(~"a").map_err(|_x| ~"b") == err(~"b");
    }
}
<commit_msg>libcore: Implement result::get_ref.<commit_after>//! A type representing either success or failure

import either::Either;

/// The result type
enum result<T, U> {
    /// Contains the successful result value
    ok(T),
    /// Contains the error value
    err(U)
}

/**
 * Get the value out of a successful result
 *
 * # Failure
 *
 * If the result is an error
 */
pure fn get<T: copy, U>(res: result<T, U>) -> T {
    match res {
      ok(t) => t,
      err(the_err) => unchecked {
        fail fmt!("get called on error result: %?", the_err)
      }
    }
}

/**
 * Get a reference to the value out of a successful result
 *
 * # Failure
 *
 * If the result is an error
 */
pure fn get_ref<T, U>(res: &a/result<T, U>) -> &a/T {
    match *res {
        ok(ref t) => t,
        err(ref the_err) => unchecked {
            fail fmt!("get_ref called on error result: %?", the_err)
        }
    }
}

/**
 * Get the value out of an error result
 *
 * # Failure
 *
 * If the result is not an error
 */
pure fn get_err<T, U: copy>(res: result<T, U>) -> U {
    match res {
      err(u) => u,
      ok(_) => fail ~"get_error called on ok result"
    }
}

/// Returns true if the result is `ok`
pure fn is_ok<T, U>(res: result<T, U>) -> bool {
    match res {
      ok(_) => true,
      err(_) => false
    }
}

/// Returns true if the result is `err`
pure fn is_err<T, U>(res: result<T, U>) -> bool {
    !is_ok(res)
}

/**
 * Convert to the `either` type
 *
 * `ok` result variants are converted to `either::right` variants, `err`
 * result variants are converted to `either::left`.
 */
pure fn to_either<T: copy, U: copy>(res: result<U, T>) -> Either<T, U> {
    match res {
      ok(res) => either::Right(res),
      err(fail_) => either::Left(fail_)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `ok` then the value is extracted and passed to `op` whereupon
 * `op`s result is returned. if `res` is `err` then it is immediately
 * returned. This function can be used to compose the results of two
 * functions.
 *
 * Example:
 *
 *     let res = chain(read_file(file)) { |buf|
 *         ok(parse_buf(buf))
 *     }
 */
fn chain<T, U: copy, V: copy>(res: result<T, V>, op: fn(T) -> result<U, V>)
    -> result<U, V> {
    match res {
      ok(t) => op(t),
      err(e) => err(e)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `err` then the value is extracted and passed to `op`
 * whereupon `op`s result is returned. if `res` is `ok` then it is
 * immediately returned.  This function can be used to pass through a
 * successful result while handling an error.
 */
fn chain_err<T: copy, U: copy, V: copy>(
    res: result<T, V>,
    op: fn(V) -> result<T, U>)
    -> result<T, U> {
    match res {
      ok(t) => ok(t),
      err(v) => op(v)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `ok` then the value is extracted and passed to `op` whereupon
 * `op`s result is returned. if `res` is `err` then it is immediately
 * returned. This function can be used to compose the results of two
 * functions.
 *
 * Example:
 *
 *     iter(read_file(file)) { |buf|
 *         print_buf(buf)
 *     }
 */
fn iter<T, E>(res: result<T, E>, f: fn(T)) {
    match res {
      ok(t) => f(t),
      err(_) => ()
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `err` then the value is extracted and passed to `op` whereupon
 * `op`s result is returned. if `res` is `ok` then it is immediately returned.
 * This function can be used to pass through a successful result while
 * handling an error.
 */
fn iter_err<T, E>(res: result<T, E>, f: fn(E)) {
    match res {
      ok(_) => (),
      err(e) => f(e)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `ok` then the value is extracted and passed to `op` whereupon
 * `op`s result is wrapped in `ok` and returned. if `res` is `err` then it is
 * immediately returned.  This function can be used to compose the results of
 * two functions.
 *
 * Example:
 *
 *     let res = map(read_file(file)) { |buf|
 *         parse_buf(buf)
 *     }
 */
fn map<T, E: copy, U: copy>(res: result<T, E>, op: fn(T) -> U)
  -> result<U, E> {
    match res {
      ok(t) => ok(op(t)),
      err(e) => err(e)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `err` then the value is extracted and passed to `op` whereupon
 * `op`s result is wrapped in an `err` and returned. if `res` is `ok` then it
 * is immediately returned.  This function can be used to pass through a
 * successful result while handling an error.
 */
fn map_err<T: copy, E, F: copy>(res: result<T, E>, op: fn(E) -> F)
  -> result<T, F> {
    match res {
      ok(t) => ok(t),
      err(e) => err(op(e))
    }
}

impl<T, E> result<T, E> {
    fn is_ok() -> bool { is_ok(self) }

    fn is_err() -> bool { is_err(self) }

    fn iter(f: fn(T)) {
        match self {
          ok(t) => f(t),
          err(_) => ()
        }
    }

    fn iter_err(f: fn(E)) {
        match self {
          ok(_) => (),
          err(e) => f(e)
        }
    }
}

impl<T: copy, E> result<T, E> {
    fn get() -> T { get(self) }

    fn map_err<F:copy>(op: fn(E) -> F) -> result<T,F> {
        match self {
          ok(t) => ok(t),
          err(e) => err(op(e))
        }
    }
}

impl<T, E: copy> result<T, E> {
    fn get_err() -> E { get_err(self) }

    fn map<U:copy>(op: fn(T) -> U) -> result<U,E> {
        match self {
          ok(t) => ok(op(t)),
          err(e) => err(e)
        }
    }
}

impl<T: copy, E: copy> result<T, E> {
    fn chain<U:copy>(op: fn(T) -> result<U,E>) -> result<U,E> {
        chain(self, op)
    }

    fn chain_err<F:copy>(op: fn(E) -> result<T,F>) -> result<T,F> {
        chain_err(self, op)
    }
}

/**
 * Maps each element in the vector `ts` using the operation `op`.  Should an
 * error occur, no further mappings are performed and the error is returned.
 * Should no error occur, a vector containing the result of each map is
 * returned.
 *
 * Here is an example which increments every integer in a vector,
 * checking for overflow:
 *
 *     fn inc_conditionally(x: uint) -> result<uint,str> {
 *         if x == uint::max_value { return err("overflow"); }
 *         else { return ok(x+1u); }
 *     }
 *     map(~[1u, 2u, 3u], inc_conditionally).chain {|incd|
 *         assert incd == ~[2u, 3u, 4u];
 *     }
 */
fn map_vec<T,U:copy,V:copy>(
    ts: &[T], op: fn(T) -> result<V,U>) -> result<~[V],U> {

    let mut vs: ~[V] = ~[];
    vec::reserve(vs, vec::len(ts));
    for vec::each(ts) |t| {
        match op(t) {
          ok(v) => vec::push(vs, v),
          err(u) => return err(u)
        }
    }
    return ok(vs);
}

fn map_opt<T,U:copy,V:copy>(
    o_t: option<T>, op: fn(T) -> result<V,U>) -> result<option<V>,U> {

    match o_t {
      none => ok(none),
      some(t) => match op(t) {
        ok(v) => ok(some(v)),
        err(e) => err(e)
      }
    }
}

/**
 * Same as map, but it operates over two parallel vectors.
 *
 * A precondition is used here to ensure that the vectors are the same
 * length.  While we do not often use preconditions in the standard
 * library, a precondition is used here because result::t is generally
 * used in 'careful' code contexts where it is both appropriate and easy
 * to accommodate an error like the vectors being of different lengths.
 */
fn map_vec2<S,T,U:copy,V:copy>(ss: &[S], ts: &[T],
                               op: fn(S,T) -> result<V,U>) -> result<~[V],U> {

    assert vec::same_length(ss, ts);
    let n = vec::len(ts);
    let mut vs = ~[];
    vec::reserve(vs, n);
    let mut i = 0u;
    while i < n {
        match op(ss[i],ts[i]) {
          ok(v) => vec::push(vs, v),
          err(u) => return err(u)
        }
        i += 1u;
    }
    return ok(vs);
}

/**
 * Applies op to the pairwise elements from `ss` and `ts`, aborting on
 * error.  This could be implemented using `map2()` but it is more efficient
 * on its own as no result vector is built.
 */
fn iter_vec2<S,T,U:copy>(ss: &[S], ts: &[T],
                         op: fn(S,T) -> result<(),U>) -> result<(),U> {

    assert vec::same_length(ss, ts);
    let n = vec::len(ts);
    let mut i = 0u;
    while i < n {
        match op(ss[i],ts[i]) {
          ok(()) => (),
          err(u) => return err(u)
        }
        i += 1u;
    }
    return ok(());
}

/// Unwraps a result, assuming it is an `ok(T)`
fn unwrap<T, U>(-res: result<T, U>) -> T {
    unsafe {
        let addr = match res {
          ok(x) => ptr::addr_of(x),
          err(_) => fail ~"error result"
        };
        let liberated_value = unsafe::reinterpret_cast(*addr);
        unsafe::forget(res);
        return liberated_value;
    }
}

#[cfg(test)]
mod tests {
    fn op1() -> result::result<int, ~str> { result::ok(666) }

    fn op2(&&i: int) -> result::result<uint, ~str> {
        result::ok(i as uint + 1u)
    }

    fn op3() -> result::result<int, ~str> { result::err(~"sadface") }

    #[test]
    fn chain_success() {
        assert get(chain(op1(), op2)) == 667u;
    }

    #[test]
    fn chain_failure() {
        assert get_err(chain(op3(), op2)) == ~"sadface";
    }

    #[test]
    fn test_impl_iter() {
        let mut valid = false;
        ok::<~str, ~str>(~"a").iter(|_x| valid = true);
        assert valid;

        err::<~str, ~str>(~"b").iter(|_x| valid = false);
        assert valid;
    }

    #[test]
    fn test_impl_iter_err() {
        let mut valid = true;
        ok::<~str, ~str>(~"a").iter_err(|_x| valid = false);
        assert valid;

        valid = false;
        err::<~str, ~str>(~"b").iter_err(|_x| valid = true);
        assert valid;
    }

    #[test]
    fn test_impl_map() {
        assert ok::<~str, ~str>(~"a").map(|_x| ~"b") == ok(~"b");
        assert err::<~str, ~str>(~"a").map(|_x| ~"b") == err(~"a");
    }

    #[test]
    fn test_impl_map_err() {
        assert ok::<~str, ~str>(~"a").map_err(|_x| ~"b") == ok(~"a");
        assert err::<~str, ~str>(~"a").map_err(|_x| ~"b") == err(~"b");
    }
}
<|endoftext|>


<commit_before>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*! Utility implementations of Reader and Writer */

use prelude::*;
use cmp;
use io;
use owned::Box;
use slice::bytes::MutableByteVector;

/// Wraps a `Reader`, limiting the number of bytes that can be read from it.
pub struct LimitReader<R> {
    limit: uint,
    inner: R
}

impl<R: Reader> LimitReader<R> {
    /// Creates a new `LimitReader`
    pub fn new(r: R, limit: uint) -> LimitReader<R> {
        LimitReader { limit: limit, inner: r }
    }

    /// Consumes the `LimitReader`, returning the underlying `Reader`.
    pub fn unwrap(self) -> R { self.inner }

    /// Returns the number of bytes that can be read before the `LimitReader`
    /// will return EOF.
    ///
    /// # Note
    ///
    /// The reader may reach EOF after reading fewer bytes than indicated by
    /// this method if the underlying reader reaches EOF.
    pub fn limit(&self) -> uint { self.limit }
}

impl<R: Reader> Reader for LimitReader<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
        if self.limit == 0 {
            return Err(io::standard_error(io::EndOfFile));
        }

        let len = cmp::min(self.limit, buf.len());
        self.inner.read(buf.mut_slice_to(len)).map(|len| {
            self.limit -= len;
            len
        })
    }
}

impl<R: Buffer> Buffer for LimitReader<R> {
    fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> {
        let amt = try!(self.inner.fill_buf());
        let buf = amt.slice_to(cmp::min(amt.len(), self.limit));
        if buf.len() == 0 {
            Err(io::standard_error(io::EndOfFile))
        } else {
            Ok(buf)
        }
    }

    fn consume(&mut self, amt: uint) {
        self.limit -= amt;
        self.inner.consume(amt);
    }

}

/// A `Writer` which ignores bytes written to it, like /dev/null.
pub struct NullWriter;

impl Writer for NullWriter {
    #[inline]
    fn write(&mut self, _buf: &[u8]) -> io::IoResult<()> { Ok(()) }
}

/// A `Reader` which returns an infinite stream of 0 bytes, like /dev/zero.
pub struct ZeroReader;

impl Reader for ZeroReader {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
        buf.set_memory(0);
        Ok(buf.len())
    }
}

impl Buffer for ZeroReader {
    fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> {
        static DATA: [u8, ..64] = [0, ..64];
        Ok(DATA.as_slice())
    }
    fn consume(&mut self, _amt: uint) {}
}

/// A `Reader` which is always at EOF, like /dev/null.
pub struct NullReader;

impl Reader for NullReader {
    #[inline]
    fn read(&mut self, _buf: &mut [u8]) -> io::IoResult<uint> {
        Err(io::standard_error(io::EndOfFile))
    }
}

impl Buffer for NullReader {
    fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> {
        Err(io::standard_error(io::EndOfFile))
    }
    fn consume(&mut self, _amt: uint) {}
}

/// A `Writer` which multiplexes writes to a set of `Writers`.
pub struct MultiWriter {
    writers: Vec<Box<Writer>>
}

impl MultiWriter {
    /// Creates a new `MultiWriter`
    pub fn new(writers: Vec<Box<Writer>>) -> MultiWriter {
        MultiWriter { writers: writers }
    }
}

impl Writer for MultiWriter {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> io::IoResult<()> {
        let mut ret = Ok(());
        for writer in self.writers.mut_iter() {
            ret = ret.and(writer.write(buf));
        }
        return ret;
    }

    #[inline]
    fn flush(&mut self) -> io::IoResult<()> {
        let mut ret = Ok(());
        for writer in self.writers.mut_iter() {
            ret = ret.and(writer.flush());
        }
        return ret;
    }
}

/// A `Reader` which chains input from multiple `Readers`, reading each to
/// completion before moving onto the next.
pub struct ChainedReader<I, R> {
    readers: I,
    cur_reader: Option<R>,
}

impl<R: Reader, I: Iterator<R>> ChainedReader<I, R> {
    /// Creates a new `ChainedReader`
    pub fn new(mut readers: I) -> ChainedReader<I, R> {
        let r = readers.next();
        ChainedReader { readers: readers, cur_reader: r }
    }
}

impl<R: Reader, I: Iterator<R>> Reader for ChainedReader<I, R> {
    fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
        loop {
            let err = match self.cur_reader {
                Some(ref mut r) => {
                    match r.read(buf) {
                        Ok(len) => return Ok(len),
                        Err(ref e) if e.kind == io::EndOfFile => None,
                        Err(e) => Some(e),
                    }
                }
                None => break
            };
            self.cur_reader = self.readers.next();
            match err {
                Some(e) => return Err(e),
                None => {}
            }
        }
        Err(io::standard_error(io::EndOfFile))
    }
}

/// A `Reader` which forwards input from another `Reader`, passing it along to
/// a `Writer` as well. Similar to the `tee(1)` command.
pub struct TeeReader<R, W> {
    reader: R,
    writer: W,
}

impl<R: Reader, W: Writer> TeeReader<R, W> {
    /// Creates a new `TeeReader`
    pub fn new(r: R, w: W) -> TeeReader<R, W> {
        TeeReader { reader: r, writer: w }
    }

    /// Consumes the `TeeReader`, returning the underlying `Reader` and
    /// `Writer`.
    pub fn unwrap(self) -> (R, W) {
        let TeeReader { reader, writer } = self;
        (reader, writer)
    }
}

impl<R: Reader, W: Writer> Reader for TeeReader<R, W> {
    fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
        self.reader.read(buf).and_then(|len| {
            self.writer.write(buf.slice_to(len)).map(|()| len)
        })
    }
}

/// Copies all data from a `Reader` to a `Writer`.
pub fn copy<R: Reader, W: Writer>(r: &mut R, w: &mut W) -> io::IoResult<()> {
    let mut buf = [0, ..super::DEFAULT_BUF_SIZE];
    loop {
        let len = match r.read(buf) {
            Ok(len) => len,
            Err(ref e) if e.kind == io::EndOfFile => return Ok(()),
            Err(e) => return Err(e),
        };
        try!(w.write(buf.slice_to(len)));
    }
}

#[cfg(test)]
mod test {
    use io::{MemReader, MemWriter, BufReader};
    use io;
    use owned::Box;
    use super::*;
    use prelude::*;

    #[test]
    fn test_limit_reader_unlimited() {
        let mut r = MemReader::new(vec!(0, 1, 2));
        {
            let mut r = LimitReader::new(r.by_ref(), 4);
            assert_eq!(vec!(0, 1, 2), r.read_to_end().unwrap());
        }
    }

    #[test]
    fn test_limit_reader_limited() {
        let mut r = MemReader::new(vec!(0, 1, 2));
        {
            let mut r = LimitReader::new(r.by_ref(), 2);
            assert_eq!(vec!(0, 1), r.read_to_end().unwrap());
        }
        assert_eq!(vec!(2), r.read_to_end().unwrap());
    }

    #[test]
    fn test_limit_reader_limit() {
        let r = MemReader::new(vec!(0, 1, 2));
        let mut r = LimitReader::new(r, 3);
        assert_eq!(3, r.limit());
        assert_eq!(0, r.read_byte().unwrap());
        assert_eq!(2, r.limit());
        assert_eq!(vec!(1, 2), r.read_to_end().unwrap());
        assert_eq!(0, r.limit());
    }

    #[test]
    fn test_null_writer() {
        let mut s = NullWriter;
        let buf = box [0, 0, 0];
        s.write(buf).unwrap();
        s.flush().unwrap();
    }

    #[test]
    fn test_zero_reader() {
        let mut s = ZeroReader;
        let mut buf = box [1, 2, 3];
        assert_eq!(s.read(buf), Ok(3));
        assert_eq!(box [0, 0, 0], buf);
    }

    #[test]
    fn test_null_reader() {
        let mut r = NullReader;
        let mut buf = box [0];
        assert!(r.read(buf).is_err());
    }

    #[test]
    fn test_multi_writer() {
        static mut writes: uint = 0;
        static mut flushes: uint = 0;

        struct TestWriter;
        impl Writer for TestWriter {
            fn write(&mut self, _buf: &[u8]) -> io::IoResult<()> {
                unsafe { writes += 1 }
                Ok(())
            }

            fn flush(&mut self) -> io::IoResult<()> {
                unsafe { flushes += 1 }
                Ok(())
            }
        }

        let mut multi = MultiWriter::new(vec!(box TestWriter as Box<Writer>,
                                              box TestWriter as Box<Writer>));
        multi.write([1, 2, 3]).unwrap();
        assert_eq!(2, unsafe { writes });
        assert_eq!(0, unsafe { flushes });
        multi.flush().unwrap();
        assert_eq!(2, unsafe { writes });
        assert_eq!(2, unsafe { flushes });
    }

    #[test]
    fn test_chained_reader() {
        let rs = vec!(MemReader::new(vec!(0, 1)), MemReader::new(vec!()),
                      MemReader::new(vec!(2, 3)));
        let mut r = ChainedReader::new(rs.move_iter());
        assert_eq!(vec!(0, 1, 2, 3), r.read_to_end().unwrap());
    }

    #[test]
    fn test_tee_reader() {
        let mut r = TeeReader::new(MemReader::new(vec!(0, 1, 2)),
                                   MemWriter::new());
        assert_eq!(vec!(0, 1, 2), r.read_to_end().unwrap());
        let (_, w) = r.unwrap();
        assert_eq!(vec!(0, 1, 2), w.unwrap());
    }

    #[test]
    fn test_copy() {
        let mut r = MemReader::new(vec!(0, 1, 2, 3, 4));
        let mut w = MemWriter::new();
        copy(&mut r, &mut w).unwrap();
        assert_eq!(vec!(0, 1, 2, 3, 4), w.unwrap());
    }

    #[test]
    fn limit_reader_buffer() {
        let data = "0123456789\n0123456789\n";
        let mut r = BufReader::new(data.as_bytes());
        {
            let mut r = LimitReader::new(r.by_ref(), 3);
            assert_eq!(r.read_line(), Ok("012".to_str()));
            assert_eq!(r.limit(), 0);
            assert_eq!(r.read_line().err().unwrap().kind, io::EndOfFile);
        }
        {
            let mut r = LimitReader::new(r.by_ref(), 9);
            assert_eq!(r.read_line(), Ok("3456789\n".to_str()));
            assert_eq!(r.limit(), 1);
            assert_eq!(r.read_line(), Ok("0".to_str()));
        }
        {
            let mut r = LimitReader::new(r.by_ref(), 100);
            assert_eq!(r.read_char(), Ok('1'));
            assert_eq!(r.limit(), 99);
            assert_eq!(r.read_line(), Ok("23456789\n".to_str()));
        }
    }
}
<commit_msg>std: add `IterReader` to adapt iterators into readers<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*! Utility implementations of Reader and Writer */

use prelude::*;
use cmp;
use io;
use owned::Box;
use slice::bytes::MutableByteVector;

/// Wraps a `Reader`, limiting the number of bytes that can be read from it.
pub struct LimitReader<R> {
    limit: uint,
    inner: R
}

impl<R: Reader> LimitReader<R> {
    /// Creates a new `LimitReader`
    pub fn new(r: R, limit: uint) -> LimitReader<R> {
        LimitReader { limit: limit, inner: r }
    }

    /// Consumes the `LimitReader`, returning the underlying `Reader`.
    pub fn unwrap(self) -> R { self.inner }

    /// Returns the number of bytes that can be read before the `LimitReader`
    /// will return EOF.
    ///
    /// # Note
    ///
    /// The reader may reach EOF after reading fewer bytes than indicated by
    /// this method if the underlying reader reaches EOF.
    pub fn limit(&self) -> uint { self.limit }
}

impl<R: Reader> Reader for LimitReader<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
        if self.limit == 0 {
            return Err(io::standard_error(io::EndOfFile));
        }

        let len = cmp::min(self.limit, buf.len());
        self.inner.read(buf.mut_slice_to(len)).map(|len| {
            self.limit -= len;
            len
        })
    }
}

impl<R: Buffer> Buffer for LimitReader<R> {
    fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> {
        let amt = try!(self.inner.fill_buf());
        let buf = amt.slice_to(cmp::min(amt.len(), self.limit));
        if buf.len() == 0 {
            Err(io::standard_error(io::EndOfFile))
        } else {
            Ok(buf)
        }
    }

    fn consume(&mut self, amt: uint) {
        self.limit -= amt;
        self.inner.consume(amt);
    }

}

/// A `Writer` which ignores bytes written to it, like /dev/null.
pub struct NullWriter;

impl Writer for NullWriter {
    #[inline]
    fn write(&mut self, _buf: &[u8]) -> io::IoResult<()> { Ok(()) }
}

/// A `Reader` which returns an infinite stream of 0 bytes, like /dev/zero.
pub struct ZeroReader;

impl Reader for ZeroReader {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
        buf.set_memory(0);
        Ok(buf.len())
    }
}

impl Buffer for ZeroReader {
    fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> {
        static DATA: [u8, ..64] = [0, ..64];
        Ok(DATA.as_slice())
    }
    fn consume(&mut self, _amt: uint) {}
}

/// A `Reader` which is always at EOF, like /dev/null.
pub struct NullReader;

impl Reader for NullReader {
    #[inline]
    fn read(&mut self, _buf: &mut [u8]) -> io::IoResult<uint> {
        Err(io::standard_error(io::EndOfFile))
    }
}

impl Buffer for NullReader {
    fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> {
        Err(io::standard_error(io::EndOfFile))
    }
    fn consume(&mut self, _amt: uint) {}
}

/// A `Writer` which multiplexes writes to a set of `Writers`.
pub struct MultiWriter {
    writers: Vec<Box<Writer>>
}

impl MultiWriter {
    /// Creates a new `MultiWriter`
    pub fn new(writers: Vec<Box<Writer>>) -> MultiWriter {
        MultiWriter { writers: writers }
    }
}

impl Writer for MultiWriter {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> io::IoResult<()> {
        let mut ret = Ok(());
        for writer in self.writers.mut_iter() {
            ret = ret.and(writer.write(buf));
        }
        return ret;
    }

    #[inline]
    fn flush(&mut self) -> io::IoResult<()> {
        let mut ret = Ok(());
        for writer in self.writers.mut_iter() {
            ret = ret.and(writer.flush());
        }
        return ret;
    }
}

/// A `Reader` which chains input from multiple `Readers`, reading each to
/// completion before moving onto the next.
pub struct ChainedReader<I, R> {
    readers: I,
    cur_reader: Option<R>,
}

impl<R: Reader, I: Iterator<R>> ChainedReader<I, R> {
    /// Creates a new `ChainedReader`
    pub fn new(mut readers: I) -> ChainedReader<I, R> {
        let r = readers.next();
        ChainedReader { readers: readers, cur_reader: r }
    }
}

impl<R: Reader, I: Iterator<R>> Reader for ChainedReader<I, R> {
    fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
        loop {
            let err = match self.cur_reader {
                Some(ref mut r) => {
                    match r.read(buf) {
                        Ok(len) => return Ok(len),
                        Err(ref e) if e.kind == io::EndOfFile => None,
                        Err(e) => Some(e),
                    }
                }
                None => break
            };
            self.cur_reader = self.readers.next();
            match err {
                Some(e) => return Err(e),
                None => {}
            }
        }
        Err(io::standard_error(io::EndOfFile))
    }
}

/// A `Reader` which forwards input from another `Reader`, passing it along to
/// a `Writer` as well. Similar to the `tee(1)` command.
pub struct TeeReader<R, W> {
    reader: R,
    writer: W,
}

impl<R: Reader, W: Writer> TeeReader<R, W> {
    /// Creates a new `TeeReader`
    pub fn new(r: R, w: W) -> TeeReader<R, W> {
        TeeReader { reader: r, writer: w }
    }

    /// Consumes the `TeeReader`, returning the underlying `Reader` and
    /// `Writer`.
    pub fn unwrap(self) -> (R, W) {
        let TeeReader { reader, writer } = self;
        (reader, writer)
    }
}

impl<R: Reader, W: Writer> Reader for TeeReader<R, W> {
    fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
        self.reader.read(buf).and_then(|len| {
            self.writer.write(buf.slice_to(len)).map(|()| len)
        })
    }
}

/// Copies all data from a `Reader` to a `Writer`.
pub fn copy<R: Reader, W: Writer>(r: &mut R, w: &mut W) -> io::IoResult<()> {
    let mut buf = [0, ..super::DEFAULT_BUF_SIZE];
    loop {
        let len = match r.read(buf) {
            Ok(len) => len,
            Err(ref e) if e.kind == io::EndOfFile => return Ok(()),
            Err(e) => return Err(e),
        };
        try!(w.write(buf.slice_to(len)));
    }
}

/// A `Reader` which converts an `Iterator<u8>` into a `Reader`.
pub struct IterReader<T> {
    iter: T,
}

impl<T: Iterator<u8>> IterReader<T> {
    /// Create a new `IterReader` which will read from the specified `Iterator`.
    pub fn new(iter: T) -> IterReader<T> {
        IterReader {
            iter: iter,
        }
    }
}

impl<T: Iterator<u8>> Reader for IterReader<T> {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
        let mut len = 0;
        for (slot, elt) in buf.mut_iter().zip(self.iter.by_ref()) {
            *slot = elt;
            len += 1;
        }
        if len == 0 {
            Err(io::standard_error(io::EndOfFile))
        } else {
            Ok(len)
        }
    }
}

#[cfg(test)]
mod test {
    use io::{MemReader, MemWriter, BufReader};
    use io;
    use owned::Box;
    use super::*;
    use prelude::*;

    #[test]
    fn test_limit_reader_unlimited() {
        let mut r = MemReader::new(vec!(0, 1, 2));
        {
            let mut r = LimitReader::new(r.by_ref(), 4);
            assert_eq!(vec!(0, 1, 2), r.read_to_end().unwrap());
        }
    }

    #[test]
    fn test_limit_reader_limited() {
        let mut r = MemReader::new(vec!(0, 1, 2));
        {
            let mut r = LimitReader::new(r.by_ref(), 2);
            assert_eq!(vec!(0, 1), r.read_to_end().unwrap());
        }
        assert_eq!(vec!(2), r.read_to_end().unwrap());
    }

    #[test]
    fn test_limit_reader_limit() {
        let r = MemReader::new(vec!(0, 1, 2));
        let mut r = LimitReader::new(r, 3);
        assert_eq!(3, r.limit());
        assert_eq!(0, r.read_byte().unwrap());
        assert_eq!(2, r.limit());
        assert_eq!(vec!(1, 2), r.read_to_end().unwrap());
        assert_eq!(0, r.limit());
    }

    #[test]
    fn test_null_writer() {
        let mut s = NullWriter;
        let buf = box [0, 0, 0];
        s.write(buf).unwrap();
        s.flush().unwrap();
    }

    #[test]
    fn test_zero_reader() {
        let mut s = ZeroReader;
        let mut buf = box [1, 2, 3];
        assert_eq!(s.read(buf), Ok(3));
        assert_eq!(box [0, 0, 0], buf);
    }

    #[test]
    fn test_null_reader() {
        let mut r = NullReader;
        let mut buf = box [0];
        assert!(r.read(buf).is_err());
    }

    #[test]
    fn test_multi_writer() {
        static mut writes: uint = 0;
        static mut flushes: uint = 0;

        struct TestWriter;
        impl Writer for TestWriter {
            fn write(&mut self, _buf: &[u8]) -> io::IoResult<()> {
                unsafe { writes += 1 }
                Ok(())
            }

            fn flush(&mut self) -> io::IoResult<()> {
                unsafe { flushes += 1 }
                Ok(())
            }
        }

        let mut multi = MultiWriter::new(vec!(box TestWriter as Box<Writer>,
                                              box TestWriter as Box<Writer>));
        multi.write([1, 2, 3]).unwrap();
        assert_eq!(2, unsafe { writes });
        assert_eq!(0, unsafe { flushes });
        multi.flush().unwrap();
        assert_eq!(2, unsafe { writes });
        assert_eq!(2, unsafe { flushes });
    }

    #[test]
    fn test_chained_reader() {
        let rs = vec!(MemReader::new(vec!(0, 1)), MemReader::new(vec!()),
                      MemReader::new(vec!(2, 3)));
        let mut r = ChainedReader::new(rs.move_iter());
        assert_eq!(vec!(0, 1, 2, 3), r.read_to_end().unwrap());
    }

    #[test]
    fn test_tee_reader() {
        let mut r = TeeReader::new(MemReader::new(vec!(0, 1, 2)),
                                   MemWriter::new());
        assert_eq!(vec!(0, 1, 2), r.read_to_end().unwrap());
        let (_, w) = r.unwrap();
        assert_eq!(vec!(0, 1, 2), w.unwrap());
    }

    #[test]
    fn test_copy() {
        let mut r = MemReader::new(vec!(0, 1, 2, 3, 4));
        let mut w = MemWriter::new();
        copy(&mut r, &mut w).unwrap();
        assert_eq!(vec!(0, 1, 2, 3, 4), w.unwrap());
    }

    #[test]
    fn limit_reader_buffer() {
        let data = "0123456789\n0123456789\n";
        let mut r = BufReader::new(data.as_bytes());
        {
            let mut r = LimitReader::new(r.by_ref(), 3);
            assert_eq!(r.read_line(), Ok("012".to_str()));
            assert_eq!(r.limit(), 0);
            assert_eq!(r.read_line().err().unwrap().kind, io::EndOfFile);
        }
        {
            let mut r = LimitReader::new(r.by_ref(), 9);
            assert_eq!(r.read_line(), Ok("3456789\n".to_str()));
            assert_eq!(r.limit(), 1);
            assert_eq!(r.read_line(), Ok("0".to_str()));
        }
        {
            let mut r = LimitReader::new(r.by_ref(), 100);
            assert_eq!(r.read_char(), Ok('1'));
            assert_eq!(r.limit(), 99);
            assert_eq!(r.read_line(), Ok("23456789\n".to_str()));
        }
    }

    #[test]
    fn test_iter_reader() {
        let mut r = IterReader::new(range(0u8, 8));
        let mut buf = [0, 0, 0];
        let len = r.read(buf).unwrap();
        assert_eq!(len, 3);
        assert!(buf == [0, 1, 2]);

        let len = r.read(buf).unwrap();
        assert_eq!(len, 3);
        assert!(buf == [3, 4, 5]);

        let len = r.read(buf).unwrap();
        assert_eq!(len, 2);
        assert!(buf == [6, 7, 5]);

        assert_eq!(r.read(buf).unwrap_err().kind, io::EndOfFile);
    }
}
<|endoftext|>