Skip to content

Commit

Permalink
python: pass paremters at jail creation time
Browse files Browse the repository at this point in the history
  • Loading branch information
fabianfreyer committed Jul 8, 2018
1 parent 3ddf2ec commit cc07461
Showing 1 changed file with 90 additions and 5 deletions.
95 changes: 90 additions & 5 deletions bindings/python/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,20 +178,105 @@ struct StoppedJail {
token: PyToken,
}

fn parameter_hashmap(dict: &PyDict) -> PyResult<HashMap<String, native::param::Value>> {
let (converted, failed): (Vec<_>, Vec<_>) = dict
.iter()
.map(|(key, value)| {
let key: PyResult<&PyString> = key
.try_into()
.map_err(|_| exc::TypeError::new("Parameter key must be a string"));
let key: PyResult<String> = key.and_then(|k| k.extract());

let py_string: Result<&PyString, PyDowncastError> = value.try_into();
let py_num: Result<&PyInt, PyDowncastError> = value.try_into();

let wrapped_value = if let Ok(string) = py_string {
string.extract().map(native::param::Value::String)
} else if let Ok(num) = py_num {
num.extract().map(native::param::Value::Int)
} else {
Err(exc::TypeError::new(
"Only string and integer parameters are supported",
))
};

(key, wrapped_value)
})
.map(|t| match t {
(Ok(key), Ok(value)) => Ok((key, value)),
(Err(e), _) => Err(e),
(_, Err(e)) => Err(e),
})
.partition(Result::is_ok);

for e in failed {
return Err(e.unwrap_err());
}

Ok(converted.into_iter().map(Result::unwrap).collect())
}

#[methods]
impl StoppedJail {
#[new]
fn __new__(obj: &PyRawObject, path: String) -> PyResult<()> {
obj.init(|token| StoppedJail {
inner: native::StoppedJail::new(path),
token,
})
fn __new__(
obj: &PyRawObject,
path: String,
name: Option<String>,
parameters: Option<&PyDict>,
) -> PyResult<()> {
let mut inner = native::StoppedJail::new(path);
inner.name = name;

if let Some(params) = parameters {
inner.params = parameter_hashmap(params)?;
}

obj.init(|token| StoppedJail { inner, token })
}

fn __repr__(&self) -> PyResult<String> {
Ok(format!("{:?}", self.inner))
}

#[getter]
fn get_parameters(&self) -> PyResult<HashMap<String, PyObject>> {
Ok(self
.inner
.params
.iter()
.filter_map(|(key, value)| {
let object = match value {
native::param::Value::Int(i) => Some(i.into_object(self.py())),
native::param::Value::String(s) => Some(s.into_object(self.py())),
native::param::Value::Ipv4Addrs(addrs) => Some(
addrs
.iter()
.map(|addr| format!("{}", addr))
.collect::<Vec<String>>()
.into_object(self.py()),
),
native::param::Value::Ipv6Addrs(addrs) => Some(
addrs
.iter()
.map(|addr| format!("{}", addr))
.collect::<Vec<String>>()
.into_object(self.py()),
),
_ => None,
};

object.map(|x| (key.clone(), x.into_object(self.py())))
})
.collect())
}

#[setter]
fn set_parameters(&mut self, dict: &PyDict) -> PyResult<()> {
self.inner.params = parameter_hashmap(dict)?;
Ok(())
}

fn start(&self) -> PyResult<Py<RunningJail>> {
let inner = self
.inner
Expand Down

0 comments on commit cc07461

Please sign in to comment.