Created
August 30, 2016 21:55
-
-
Save lilith/044ae7d10733751ad4c8b583e7bad5c1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(alloc)] | |
#![feature(oom)] | |
pub mod ffi; | |
pub mod boring; | |
pub mod parsing; | |
#[macro_use] | |
extern crate json; | |
extern crate libc; | |
extern crate alloc; | |
use std::ptr; | |
use std::cell::RefCell; | |
struct ContextPtr { | |
ptr: Option<*mut ::ffi::Context> | |
} | |
pub struct Context{ | |
p: RefCell<ContextPtr> | |
} | |
struct JobPtr{ | |
ptr: Option<*mut ::ffi::Job> | |
} | |
pub struct Job{ | |
p: RefCell<JobPtr> | |
} | |
#[derive(Debug, PartialEq)] | |
pub enum FlowError { | |
ContextInvalid, | |
Oom, | |
ErrNotImpl | |
} | |
pub type Result<T> = std::result::Result<T, FlowError>; | |
impl ContextPtr { | |
fn destroy(&mut self){ | |
unsafe { | |
self.ptr = match self.ptr{ | |
Some(ptr) => { | |
::ffi::flow_context_destroy(ptr); | |
None | |
} | |
_ => None | |
} | |
} | |
} | |
} | |
impl Drop for Context { | |
fn drop(&mut self) { | |
(*self.p.borrow_mut()).destroy(); | |
} | |
} | |
impl Context { | |
pub fn create() -> Context { | |
unsafe { | |
let ptr = ::ffi::flow_context_create(); | |
if ptr.is_null() { | |
panic!("OOM"); | |
} else { | |
Context { | |
p: RefCell::new(ContextPtr { ptr: Some(ptr) }), | |
} | |
} | |
} | |
} | |
fn get_error_copy(&self) -> Option<FlowError> { | |
unsafe { | |
match (*self.p.borrow()).ptr { | |
Some(ptr) if ::ffi::flow_context_has_error(ptr) => Some(FlowError::ErrNotImpl), | |
None => Some(FlowError::ContextInvalid), | |
Some(_) => None | |
} | |
} | |
} | |
pub fn destroy(&mut self) -> Result<()> { | |
let ref mut b = *self.p.borrow_mut(); | |
match b.ptr { | |
None => Ok(()), | |
Some(ptr) => unsafe { | |
if !::ffi::flow_context_begin_terminate(ptr) { | |
//Already borrowed; will panic! | |
//This kind of bug is only exposed at runtime, now. | |
//Code reuse will require two copies of every function | |
//One against the ContextPtr, to be reused | |
//One exposed publicly against the Context, which performs the borrowing | |
//Same scenario will occur with other types. | |
let copy = self.get_error_copy().unwrap(); | |
b.destroy(); | |
Err(copy) | |
} else { | |
b.destroy(); | |
Ok(()) | |
} | |
} | |
} | |
} | |
pub fn create_job(&mut self) -> Result<Job> { | |
let ref b = *self.p.borrow_mut(); | |
match b.ptr { | |
None => Err(FlowError::ContextInvalid), | |
Some(ptr) => unsafe { | |
let p = ::ffi::flow_job_create(ptr); | |
if p.is_null() { | |
Err(FlowError::Oom) | |
} else { | |
Ok(Job { p: RefCell::new(JobPtr { ptr: Some(p) }) }) | |
} | |
} | |
} | |
} | |
} | |
#[test] | |
fn it_works() { | |
let mut c = Context::create(); | |
let j = c.create_job().unwrap(); | |
let j2 = c.create_job().unwrap(); | |
assert_eq!(c.destroy(), Ok(())); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment