1use mpack::{self, Value, ValueMap};
2use std::convert;
3use std::error;
4use std::fmt;
5
6pub struct Metadata {
8 pub buffer_id: i64,
9 pub window_id: i64,
10 pub tabpage_id: i64,
11}
12
13#[derive(Debug)]
14pub enum GetMetadataError {
15 NotAMap,
17 NoTypeInformation,
19 Missing(String),
21 Invalid(String),
23 ReadError(mpack::ReadError),
25}
26
27impl fmt::Display for GetMetadataError {
28 fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
29 write!(fmt, "{}", self)
30 }
31}
32
33impl error::Error for GetMetadataError {
34 fn description(&self) -> &str {
35 match *self {
36 GetMetadataError::NotAMap => "not a map",
37 GetMetadataError::NoTypeInformation => "no type information",
38 GetMetadataError::Invalid(_) => "invalid id",
39 GetMetadataError::Missing(_) => "missing id",
40 GetMetadataError::ReadError(_) => "read error",
41 }
42 }
43
44 fn cause(&self) -> Option<&error::Error> {
45 match *self {
46 GetMetadataError::ReadError(ref e) => Some(e as &error::Error),
47 _ => None,
48 }
49 }
50}
51
52impl convert::From<mpack::ReadError> for GetMetadataError {
53 fn from(err: mpack::ReadError) -> GetMetadataError {
54 GetMetadataError::ReadError(err)
55 }
56}
57
58impl Metadata {
59 pub fn new(metadata: Value) -> Result<Metadata, GetMetadataError> {
77 let metadata = match metadata.map() {
78 Ok(m) => m,
79 Err(_) => return Err(GetMetadataError::NotAMap),
80 };
81
82 let types = match metadata.get("types") {
83 Some(t) => t.clone().map().unwrap(),
84 None => return Err(GetMetadataError::NoTypeInformation),
85 };
86
87 fn get_id(types: &ValueMap, name: &'static str) -> Result<i64, GetMetadataError> {
88 let ob = match types.get(name) {
89 Some(v) => match v.clone().map() {
90 Ok(ob) => ob,
91 Err(_) => return Err(GetMetadataError::Missing(format!("{}.id", name))),
92 },
93 None => return Err(GetMetadataError::Missing(format!("{}.id", name))),
94 };
95
96 match ob.get("id") {
97 Some(id) => Ok(id.clone().int().unwrap()),
98 None => return Err(GetMetadataError::Invalid(format!("{}.id", name))),
99 }
100 }
101
102 Ok(Metadata {
103 buffer_id: try!(get_id(&types, "Buffer")),
104 window_id: try!(get_id(&types, "Window")),
105 tabpage_id: try!(get_id(&types, "Tabpage")),
106 })
107 }
108}