Skip to content

Commit 05a35e3

Browse files
committed
improve generator
1 parent d4394e0 commit 05a35e3

File tree

4 files changed

+164
-55
lines changed

4 files changed

+164
-55
lines changed

examples/io_systemd_network/mod.rs

+6-10
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ use std::result::Result;
44
use std::convert::From;
55
use std::borrow::Cow;
66

7-
use varlink::server::Interface as VarlinkInterface;
8-
use varlink::server::Error as VarlinkError;
7+
use varlink;
98

10-
pub trait Interface: VarlinkInterface {
9+
pub trait Interface: varlink::server::Interface {
1110
fn info(&self, i64) -> Result<InfoReply, Error>;
1211
fn list(&self) -> Result<ListReply, Error>;
1312
}
@@ -18,12 +17,9 @@ macro_rules! IoSystemdNetwork {
1817
()
1918
$(pub)* struct $name:ident $($_tail:tt)*
2019
) => {
21-
use varlink::server::{Request};
22-
use varlink::server::Interface as VarlinkInterface;
23-
use varlink::server::Error as VarlinkError;
2420
use serde_json::Value as SerdeValue;
2521

26-
impl VarlinkInterface for $name {
22+
impl varlink::server::Interface for $name {
2723
fn get_description(&self) -> &'static str {
2824
r#"
2925
# Provides information about network state
@@ -54,7 +50,7 @@ error InvalidParameter (field: string)
5450
"io.systemd.network"
5551
}
5652

57-
fn call(&self, req: Request) -> Result<SerdeValue, VarlinkError> {
53+
fn call(&self, req: varlink::server::Request) -> Result<SerdeValue, varlink::server::Error> {
5854
match req.method.as_ref() {
5955
"io.systemd.network.Info" => {
6056
if let Some(args) = req.parameters {
@@ -93,9 +89,9 @@ impl From<serde_json::Error> for Error {
9389
}
9490
}
9591

96-
impl From<Error> for VarlinkError {
92+
impl From<Error> for varlink::server::Error {
9793
fn from(e: Error) -> Self {
98-
VarlinkError {
94+
varlink::server::Error {
9995
error: match e {
10096
Error::UnknownNetworkDevice => "io.systemd.network.UnknownNetworkDevice".into(),
10197
Error::InvalidParameter => "org.varlink.service.InvalidParameter".into(),

examples/varlink-generator.rs

+104-23
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ use std::error::Error;
1414
use std::result::Result;
1515
use varlink::parser::*;
1616
use std::fmt;
17+
use std::collections::HashMap;
18+
use std::iter::FromIterator;
19+
20+
type EnumHash<'a> = HashMap<String, Vec<String>>;
1721

1822
trait MainReturn {
1923
fn into_error_code(self) -> i32;
@@ -31,27 +35,24 @@ impl<E: Error> MainReturn for Result<(), E> {
3135
}
3236

3337
trait ToRust {
34-
fn to_rust(&self) -> Result<String, ToRustError>;
38+
fn to_rust(&self, parent: &str, enumhash: &mut EnumHash) -> Result<String, ToRustError>;
3539
}
3640

3741
#[derive(Debug)]
3842
enum ToRustError {
39-
BadStruct,
4043
IoError(IOError),
4144
}
4245

4346
impl Error for ToRustError {
4447
fn description(&self) -> &str {
4548
match *self {
46-
ToRustError::BadStruct => "Anonymous struct",
4749
ToRustError::IoError(_) => "an I/O error occurred",
4850
}
4951
}
5052

5153
fn cause(&self) -> Option<&Error> {
5254
match self {
5355
&ToRustError::IoError(ref err) => Some(&*err as &Error),
54-
_ => None,
5556
}
5657
}
5758
}
@@ -71,22 +72,27 @@ impl fmt::Display for ToRustError {
7172
}
7273

7374
impl<'a> ToRust for VType<'a> {
74-
fn to_rust(&self) -> Result<String, ToRustError> {
75+
fn to_rust(&self, parent: &str, enumhash: &mut EnumHash) -> Result<String, ToRustError> {
7576
match *self {
7677
VType::Bool(_) => Ok("bool".into()),
7778
VType::Int(_) => Ok("i64".into()),
7879
VType::Float(_) => Ok("f64".into()),
7980
VType::VString(_) => Ok("String".into()),
8081
VType::VData(_) => Ok("String".into()),
8182
VType::VTypename(v) => Ok(v.into()),
82-
VType::VStruct(_) => Err(ToRustError::BadStruct),
83+
VType::VEnum(ref v) => {
84+
enumhash.insert(parent.into(),
85+
Vec::from_iter(v.elts.iter().map(|s| String::from(*s))));
86+
Ok(format!("{}", parent).into())
87+
}
88+
VType::VStruct(_) => Ok(format!("{}", parent).into()),
8389
}
8490
}
8591
}
8692

8793
impl<'a> ToRust for VTypeExt<'a> {
88-
fn to_rust(&self) -> Result<String, ToRustError> {
89-
let v = self.vtype.to_rust()?;
94+
fn to_rust(&self, parent: &str, enumhash: &mut EnumHash) -> Result<String, ToRustError> {
95+
let v = self.vtype.to_rust(parent, enumhash)?;
9096

9197
if self.isarray {
9298
Ok(format!("Vec<{}>", v).into())
@@ -97,45 +103,110 @@ impl<'a> ToRust for VTypeExt<'a> {
97103
}
98104

99105
impl<'a> ToRust for Interface<'a> {
100-
fn to_rust(&self) -> Result<String, ToRustError> {
106+
fn to_rust(&self, _: &str, _: &mut EnumHash) -> Result<String, ToRustError> {
101107
let mut out: String = "".to_owned();
108+
let mut enumhash = EnumHash::new();
102109

103110
for t in self.typedefs.values() {
104111
out += "#[derive(Serialize, Deserialize, Debug)]\n";
105-
out += format!("pub struct {} {{\n", t.name).as_ref();
106-
for e in &t.vstruct.elts {
107-
let v = &e.vtypes[0];
108-
out += format!(" pub {} : {},\n", e.name, v.to_rust()?).as_ref();
112+
match t.elt {
113+
VStructOrEnum::VStruct(ref v) => {
114+
out += format!("pub struct {} {{\n", t.name).as_ref();
115+
for e in &v.elts {
116+
out += format!(" pub {}: Option<{}>,\n",
117+
e.name,
118+
e.vtype
119+
.to_rust(format!("{}_{}", t.name, e.name).as_ref(),
120+
&mut enumhash)?)
121+
.as_ref();
122+
}
123+
}
124+
VStructOrEnum::VEnum(ref v) => {
125+
out += format!("pub enum {} {{\n", t.name).as_ref();
126+
let mut iter = v.elts.iter();
127+
if let Some(fst) = iter.next() {
128+
out += format!(" {}", fst).as_ref();
129+
for elt in iter {
130+
out += format!(",\n {}", elt).as_ref();
131+
}
132+
}
133+
out += "\n";
134+
}
109135
}
110136
out += "}\n\n";
111137
}
112138

113139
for t in self.methods.values() {
114-
out += "#[derive(Serialize, Deserialize, Debug)]\n";
115-
out += format!("pub struct {}Reply {{\n", t.name).as_ref();
116-
for e in &t.output.elts {
117-
let v = &e.vtypes[0];
118-
out += format!(" pub {} : {},\n", e.name, v.to_rust()?).as_ref();
140+
if t.output.elts.len() > 0 {
141+
out += "#[derive(Serialize, Deserialize, Debug)]\n";
142+
out += format!("pub struct {}Reply {{\n", t.name).as_ref();
143+
for e in &t.output.elts {
144+
out += format!(" pub {}: Option<{}>,\n",
145+
e.name,
146+
e.vtype.to_rust(self.name, &mut enumhash)?)
147+
.as_ref();
148+
}
149+
out += "}\n\n";
119150
}
120-
out += "}\n\n";
121151

122152
if t.input.elts.len() > 0 {
123153
out += "#[derive(Serialize, Deserialize, Debug)]\n";
124154
out += format!("pub struct {}Args {{\n", t.name).as_ref();
125155
for e in &t.input.elts {
126-
let v = &e.vtypes[0];
127-
out += format!(" pub {} : {},\n", e.name, v.to_rust()?).as_ref();
156+
out += format!(" pub {}: Option<{}>,\n",
157+
e.name,
158+
e.vtype.to_rust(self.name, &mut enumhash)?)
159+
.as_ref();
128160
}
129161
out += "}\n\n";
130162
}
163+
131164
}
165+
166+
for (name, v) in &enumhash {
167+
out += format!("pub enum {} {{\n", name).as_ref();
168+
let mut iter = v.iter();
169+
if let Some(fst) = iter.next() {
170+
out += format!(" {}", fst).as_ref();
171+
for elt in iter {
172+
out += format!(",\n {}", elt).as_ref();
173+
}
174+
}
175+
out += "\n}\n\n";
176+
}
177+
178+
out += "pub trait Interface: VarlinkInterface {\n";
179+
for t in self.methods.values() {
180+
let mut inparms: String = "".to_owned();
181+
if t.input.elts.len() > 0 {
182+
for e in &t.input.elts {
183+
inparms += format!(", {} : {}",
184+
e.name,
185+
e.vtype.to_rust(self.name, &mut enumhash)?)
186+
.as_ref();
187+
}
188+
}
189+
let mut c = t.name.chars();
190+
let fname = match c.next() {
191+
None => String::from(t.name),
192+
Some(f) => f.to_lowercase().chain(c).collect(),
193+
};
194+
195+
out += format!(" fn {}(&self{}) -> Result<{}Reply, Error>;\n",
196+
fname,
197+
inparms,
198+
t.name)
199+
.as_ref();
200+
}
201+
out += "}\n\n";
202+
132203
Ok(out)
133204
}
134205
}
135206

136207
fn do_main() -> Result<(), ToRustError> {
137208
let mut buffer = String::new();
138-
209+
let mut enumhash = EnumHash::new();
139210
let args: Vec<_> = env::args().collect();
140211
match args.len() {
141212
0 | 1 => io::stdin().read_to_string(&mut buffer)?,
@@ -152,7 +223,17 @@ fn do_main() -> Result<(), ToRustError> {
152223
exit(1);
153224
}
154225

155-
println!("{}", vr.unwrap().interface.to_rust()?);
226+
println!(
227+
r#"
228+
use serde_json;
229+
use std::result::Result;
230+
use std::convert::From;
231+
use std::borrow::Cow;
232+
use varlink;
233+
234+
{}"#,
235+
vr.unwrap().interface.to_rust("", &mut enumhash)?
236+
);
156237

157238
Ok(())
158239
}

src/parser.rs

+39-14
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub enum VType<'a> {
1616
VData(Option<&'a str>),
1717
VTypename(&'a str),
1818
VStruct(Box<VStruct<'a>>),
19+
VEnum(Box<VEnum<'a>>),
1920
}
2021

2122
pub struct VTypeExt<'a> {
@@ -25,21 +26,30 @@ pub struct VTypeExt<'a> {
2526

2627
pub struct Argument<'a> {
2728
pub name: &'a str,
28-
pub vtypes: Vec<VTypeExt<'a>>,
29+
pub vtype: VTypeExt<'a>,
2930
}
3031

3132
pub struct VStruct<'a> {
3233
pub elts: Vec<Argument<'a>>,
3334
}
3435

36+
pub struct VEnum<'a> {
37+
pub elts: Vec<&'a str>,
38+
}
39+
3540
pub struct VError<'a> {
3641
pub name: &'a str,
3742
pub parm: VStruct<'a>,
3843
}
3944

45+
pub enum VStructOrEnum<'a> {
46+
VStruct(Box<VStruct<'a>>),
47+
VEnum(Box<VEnum<'a>>),
48+
}
49+
4050
pub struct Typedef<'a> {
4151
pub name: &'a str,
42-
pub vstruct: VStruct<'a>,
52+
pub elt: VStructOrEnum<'a>,
4353
}
4454

4555
pub struct Method<'a> {
@@ -100,29 +110,30 @@ impl<'a> fmt::Display for VTypeExt<'a> {
100110
VType::VData(ref v) => printVTypeExt!(self, f, v, "data", "\""),
101111
VType::VTypename(ref v) => printVTypeExt!(self, f, v),
102112
VType::VStruct(ref v) => printVTypeExt!(self, f, v),
113+
VType::VEnum(ref v) => printVTypeExt!(self, f, v),
103114
}
104115

105116
Ok(())
106117
}
107118
}
108119

109-
impl<'a> fmt::Display for Argument<'a> {
120+
impl<'a> fmt::Display for VStructOrEnum<'a> {
110121
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
111-
if self.vtypes.len() == 1 {
112-
write!(f, "{}: {}", self.name, self.vtypes[0])?;
113-
} else {
114-
let mut iter = self.vtypes.iter();
115-
if let Some(fst) = iter.next() {
116-
write!(f, "{}: {}", self.name, fst)?;
117-
for elt in iter {
118-
write!(f, " , {}", elt)?;
119-
}
120-
}
122+
match *self {
123+
VStructOrEnum::VStruct(ref v) => write!(f, "{}", v)?,
124+
VStructOrEnum::VEnum(ref v) => write!(f, "{}", v)?,
121125
}
126+
122127
Ok(())
123128
}
124129
}
125130

131+
impl<'a> fmt::Display for Argument<'a> {
132+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
133+
write!(f, "{}: {}", self.name, self.vtype)?;
134+
Ok(())
135+
}
136+
}
126137
impl<'a> fmt::Display for VStruct<'a> {
127138
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
128139
write!(f, "(")?;
@@ -137,12 +148,26 @@ impl<'a> fmt::Display for VStruct<'a> {
137148
}
138149
}
139150

151+
impl<'a> fmt::Display for VEnum<'a> {
152+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
153+
write!(f, "(")?;
154+
let mut iter = self.elts.iter();
155+
if let Some(fst) = iter.next() {
156+
write!(f, "{}", fst)?;
157+
for elt in iter {
158+
write!(f, ", {}", elt)?;
159+
}
160+
}
161+
write!(f, ")")
162+
}
163+
}
164+
140165
impl<'a> fmt::Display for Interface<'a> {
141166
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
142167
write!(f, "interface {}\n", self.name)?;
143168

144169
for t in self.typedefs.values() {
145-
write!(f, "type {} {}\n", t.name, t.vstruct)?;
170+
write!(f, "type {} {}\n", t.name, t.elt)?;
146171
}
147172

148173
for m in self.methods.values() {

0 commit comments

Comments
 (0)