// *** Original Rust Type Printing ***
// ***********************************
- fn write_rust_path<W: std::io::Write>(&self, w: &mut W, path: &syn::Path) {
- if let Some(resolved) = self.maybe_resolve_path(&path, None) {
+ fn in_rust_prelude(resolved_path: &str) -> bool {
+ match resolved_path {
+ "Vec" => true,
+ "Result" => true,
+ "Option" => true,
+ _ => false,
+ }
+ }
+
+ fn write_rust_path<W: std::io::Write>(&self, w: &mut W, generics_resolver: Option<&GenericTypes>, path: &syn::Path) {
+ if let Some(resolved) = self.maybe_resolve_path(&path, generics_resolver) {
if self.is_primitive(&resolved) {
write!(w, "{}", path.get_ident().unwrap()).unwrap();
} else {
- if resolved.starts_with("ln::") || resolved.starts_with("chain::") || resolved.starts_with("util::") {
- write!(w, "lightning::{}", resolved).unwrap();
+ // TODO: We should have a generic "is from a dependency" check here instead of
+ // checking for "bitcoin" explicitly.
+ if resolved.starts_with("bitcoin::") || Self::in_rust_prelude(&resolved) {
+ write!(w, "{}", resolved).unwrap();
+ // If we're printing a generic argument, it needs to reference the crate, otherwise
+ // the original crate:
+ } else if self.maybe_resolve_path(&path, None).as_ref() == Some(&resolved) {
+ write!(w, "{}::{}", self.orig_crate, resolved).unwrap();
} else {
- write!(w, "{}", resolved).unwrap(); // XXX: Probably doens't work, get_ident().unwrap()
+ write!(w, "crate::{}", resolved).unwrap();
}
}
if let syn::PathArguments::AngleBracketed(args) = &path.segments.iter().last().unwrap().arguments {
- self.write_rust_generic_arg(w, args.args.iter());
+ self.write_rust_generic_arg(w, generics_resolver, args.args.iter());
}
} else {
if path.leading_colon.is_some() {
if idx != 0 { write!(w, "::").unwrap(); }
write!(w, "{}", seg.ident).unwrap();
if let syn::PathArguments::AngleBracketed(args) = &seg.arguments {
- self.write_rust_generic_arg(w, args.args.iter());
+ self.write_rust_generic_arg(w, generics_resolver, args.args.iter());
}
}
}
}
- pub fn write_rust_generic_param<'b, W: std::io::Write>(&self, w: &mut W, generics: impl Iterator<Item=&'b syn::GenericParam>) {
+ pub fn write_rust_generic_param<'b, W: std::io::Write>(&self, w: &mut W, generics_resolver: Option<&GenericTypes>, generics: impl Iterator<Item=&'b syn::GenericParam>) {
let mut had_params = false;
for (idx, arg) in generics.enumerate() {
if idx != 0 { write!(w, ", ").unwrap(); } else { write!(w, "<").unwrap(); }
match bound {
syn::TypeParamBound::Trait(tb) => {
if tb.paren_token.is_some() || tb.lifetimes.is_some() { unimplemented!(); }
- self.write_rust_path(w, &tb.path);
+ self.write_rust_path(w, generics_resolver, &tb.path);
},
_ => unimplemented!(),
}
if had_params { write!(w, ">").unwrap(); }
}
- pub fn write_rust_generic_arg<'b, W: std::io::Write>(&self, w: &mut W, generics: impl Iterator<Item=&'b syn::GenericArgument>) {
+ pub fn write_rust_generic_arg<'b, W: std::io::Write>(&self, w: &mut W, generics_resolver: Option<&GenericTypes>, generics: impl Iterator<Item=&'b syn::GenericArgument>) {
write!(w, "<").unwrap();
for (idx, arg) in generics.enumerate() {
if idx != 0 { write!(w, ", ").unwrap(); }
match arg {
- syn::GenericArgument::Type(t) => self.write_rust_type(w, t),
+ syn::GenericArgument::Type(t) => self.write_rust_type(w, generics_resolver, t),
_ => unimplemented!(),
}
}
write!(w, ">").unwrap();
}
- pub fn write_rust_type<W: std::io::Write>(&self, w: &mut W, t: &syn::Type) {
+ pub fn write_rust_type<W: std::io::Write>(&self, w: &mut W, generics: Option<&GenericTypes>, t: &syn::Type) {
match t {
syn::Type::Path(p) => {
if p.qself.is_some() || p.path.leading_colon.is_some() {
unimplemented!();
}
- self.write_rust_path(w, &p.path);
+ self.write_rust_path(w, generics, &p.path);
},
syn::Type::Reference(r) => {
write!(w, "&").unwrap();
if r.mutability.is_some() {
write!(w, "mut ").unwrap();
}
- self.write_rust_type(w, &*r.elem);
+ self.write_rust_type(w, generics, &*r.elem);
},
syn::Type::Array(a) => {
write!(w, "[").unwrap();
- self.write_rust_type(w, &a.elem);
+ self.write_rust_type(w, generics, &a.elem);
if let syn::Expr::Lit(l) = &a.len {
if let syn::Lit::Int(i) = &l.lit {
write!(w, "; {}]", i).unwrap();
}
syn::Type::Slice(s) => {
write!(w, "[").unwrap();
- self.write_rust_type(w, &s.elem);
+ self.write_rust_type(w, generics, &s.elem);
write!(w, "]").unwrap();
},
syn::Type::Tuple(s) => {
write!(w, "(").unwrap();
for (idx, t) in s.elems.iter().enumerate() {
if idx != 0 { write!(w, ", ").unwrap(); }
- self.write_rust_type(w, &t);
+ self.write_rust_type(w, generics, &t);
}
write!(w, ")").unwrap();
},
} else if in_crate {
write!(w, "{}", c_type).unwrap();
} else {
- self.write_rust_type(w, &t);
+ self.write_rust_type(w, None, &t);
}
} else {
// If we just write out resolved_generic, it may mostly work, however for