Skip to content

Commit fdd4cf3

Browse files
committed
Provide fn stringify_type in gen/src/write.rs.
This commit refactors `write_...` functions to enable formatting a C++ representation of a `Type` into any generic `impl std::fmt::Write` instead of only supporting formatting into an `OutFile`. This is then used to provide `fn stringify_type`. The new function is not used in this commit, but will become quite handy in a follow-up commit when `inner` type of generics/templates may not necessarily be a simple `std::fmt`-friendly `Type::Ident`. Without the refactored `write_...` APIs, the follow-up would have to split *single* `writeln!` invocations (such as the ones in `fn write_shared_ptr` or `fn write_cxx_vector`) into *multiple* ones - e.g. into: `write!` + `write_type` + `write!` + `write_type` + `writeln!`. The new function is a little bit redundant wrt the already existing `trait ToTypename`, but we can't replace that trait just yet: * The trait has slightly different semantics (formatting not the whole type represented by `self`, but only formatting the inner `T`). * The trait works with `Ident` rather than `Type` (this will change in the follow-up commit mentioned above).
1 parent e197216 commit fdd4cf3

File tree

2 files changed

+88
-46
lines changed

2 files changed

+88
-46
lines changed

gen/src/out.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,13 @@ impl<'a> Write for Content<'a> {
122122
}
123123
}
124124

125+
impl<'a> Write for OutFile<'a> {
126+
fn write_str(&mut self, s: &str) -> fmt::Result {
127+
self.content.borrow_mut().write(s);
128+
Ok(())
129+
}
130+
}
131+
125132
impl<'a> PartialEq for Content<'a> {
126133
fn eq(&self, _other: &Self) -> bool {
127134
true

gen/src/write.rs

Lines changed: 81 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,95 +1409,110 @@ fn write_extern_arg(out: &mut OutFile, arg: &Var) {
14091409
}
14101410

14111411
fn write_type(out: &mut OutFile, ty: &Type) {
1412+
write!(out, "{}", stringify_type(ty, out.types));
1413+
}
1414+
1415+
fn stringify_type(ty: &Type, types: &Types) -> String {
1416+
let mut s = String::new();
1417+
write_type_to_generic_writer(&mut s, ty, types).unwrap();
1418+
s
1419+
}
1420+
1421+
fn write_type_to_generic_writer(
1422+
out: &mut impl std::fmt::Write,
1423+
ty: &Type,
1424+
types: &Types,
1425+
) -> std::fmt::Result {
14121426
match ty {
14131427
Type::Ident(ident) => match Atom::from(&ident.rust) {
1414-
Some(atom) => write_atom(out, atom),
1415-
None => write!(
1416-
out,
1417-
"{}",
1418-
out.types.resolve(ident).name.to_fully_qualified(),
1419-
),
1428+
Some(atom) => write_atom_to_generic_writer(out, atom),
1429+
None => write!(out, "{}", types.resolve(ident).name.to_fully_qualified()),
14201430
},
14211431
Type::RustBox(ty) => {
1422-
write!(out, "::rust::Box<");
1423-
write_type(out, &ty.inner);
1424-
write!(out, ">");
1432+
write!(out, "::rust::Box<")?;
1433+
write_type_to_generic_writer(out, &ty.inner, types)?;
1434+
write!(out, ">")
14251435
}
14261436
Type::RustVec(ty) => {
1427-
write!(out, "::rust::Vec<");
1428-
write_type(out, &ty.inner);
1429-
write!(out, ">");
1437+
write!(out, "::rust::Vec<")?;
1438+
write_type_to_generic_writer(out, &ty.inner, types)?;
1439+
write!(out, ">")
14301440
}
14311441
Type::UniquePtr(ptr) => {
1432-
write!(out, "::std::unique_ptr<");
1433-
write_type(out, &ptr.inner);
1434-
write!(out, ">");
1442+
write!(out, "::std::unique_ptr<")?;
1443+
write_type_to_generic_writer(out, &ptr.inner, types)?;
1444+
write!(out, ">")
14351445
}
14361446
Type::SharedPtr(ptr) => {
1437-
write!(out, "::std::shared_ptr<");
1438-
write_type(out, &ptr.inner);
1439-
write!(out, ">");
1447+
write!(out, "::std::shared_ptr<")?;
1448+
write_type_to_generic_writer(out, &ptr.inner, types)?;
1449+
write!(out, ">")
14401450
}
14411451
Type::WeakPtr(ptr) => {
1442-
write!(out, "::std::weak_ptr<");
1443-
write_type(out, &ptr.inner);
1444-
write!(out, ">");
1452+
write!(out, "::std::weak_ptr<")?;
1453+
write_type_to_generic_writer(out, &ptr.inner, types)?;
1454+
write!(out, ">")
14451455
}
14461456
Type::CxxVector(ty) => {
1447-
write!(out, "::std::vector<");
1448-
write_type(out, &ty.inner);
1449-
write!(out, ">");
1457+
write!(out, "::std::vector<")?;
1458+
write_type_to_generic_writer(out, &ty.inner, types)?;
1459+
write!(out, ">")
14501460
}
14511461
Type::Ref(r) => {
1452-
write_type_space(out, &r.inner);
1462+
write_type_space_to_generic_writer(out, &r.inner, types)?;
14531463
if !r.mutable {
1454-
write!(out, "const ");
1464+
write!(out, "const ")?;
14551465
}
1456-
write!(out, "&");
1466+
write!(out, "&")
14571467
}
14581468
Type::Ptr(p) => {
1459-
write_type_space(out, &p.inner);
1469+
write_type_space_to_generic_writer(out, &p.inner, types)?;
14601470
if !p.mutable {
1461-
write!(out, "const ");
1471+
write!(out, "const ")?;
14621472
}
1463-
write!(out, "*");
1473+
write!(out, "*")
14641474
}
14651475
Type::Str(_) => {
1466-
write!(out, "::rust::Str");
1476+
write!(out, "::rust::Str")
14671477
}
14681478
Type::SliceRef(slice) => {
1469-
write!(out, "::rust::Slice<");
1470-
write_type_space(out, &slice.inner);
1479+
write!(out, "::rust::Slice<")?;
1480+
write_type_space_to_generic_writer(out, &slice.inner, types)?;
14711481
if slice.mutability.is_none() {
1472-
write!(out, "const");
1482+
write!(out, "const")?;
14731483
}
1474-
write!(out, ">");
1484+
write!(out, ">")
14751485
}
14761486
Type::Fn(f) => {
1477-
write!(out, "::rust::Fn<");
1487+
write!(out, "::rust::Fn<")?;
14781488
match &f.ret {
1479-
Some(ret) => write_type(out, ret),
1480-
None => write!(out, "void"),
1489+
Some(ret) => write_type_to_generic_writer(out, ret, types)?,
1490+
None => write!(out, "void")?,
14811491
}
1482-
write!(out, "(");
1492+
write!(out, "(")?;
14831493
for (i, arg) in f.args.iter().enumerate() {
14841494
if i > 0 {
1485-
write!(out, ", ");
1495+
write!(out, ", ")?;
14861496
}
1487-
write_type(out, &arg.ty);
1497+
write_type_to_generic_writer(out, &arg.ty, types)?;
14881498
}
1489-
write!(out, ")>");
1499+
write!(out, ")>")
14901500
}
14911501
Type::Array(a) => {
1492-
write!(out, "::std::array<");
1493-
write_type(out, &a.inner);
1494-
write!(out, ", {}>", &a.len);
1502+
write!(out, "::std::array<")?;
1503+
write_type_to_generic_writer(out, &a.inner, types)?;
1504+
write!(out, ", {}>", &a.len)
14951505
}
14961506
Type::Void(_) => unreachable!(),
14971507
}
14981508
}
14991509

15001510
fn write_atom(out: &mut OutFile, atom: Atom) {
1511+
// `unwrap`, because `OutFile`'s impl of `fmt::Write` is infallible.
1512+
write_atom_to_generic_writer(out, atom).unwrap();
1513+
}
1514+
1515+
fn write_atom_to_generic_writer(out: &mut impl std::fmt::Write, atom: Atom) -> std::fmt::Result {
15011516
match atom {
15021517
Bool => write!(out, "bool"),
15031518
Char => write!(out, "char"),
@@ -1523,7 +1538,24 @@ fn write_type_space(out: &mut OutFile, ty: &Type) {
15231538
write_space_after_type(out, ty);
15241539
}
15251540

1541+
fn write_type_space_to_generic_writer(
1542+
out: &mut impl std::fmt::Write,
1543+
ty: &Type,
1544+
types: &Types,
1545+
) -> std::fmt::Result {
1546+
write_type_to_generic_writer(out, ty, types)?;
1547+
write_space_after_type_to_generic_writer(out, ty)
1548+
}
1549+
15261550
fn write_space_after_type(out: &mut OutFile, ty: &Type) {
1551+
// `unwrap`, because `OutFile`'s impl of `fmt::Write` is infallible.
1552+
write_space_after_type_to_generic_writer(out, ty).unwrap();
1553+
}
1554+
1555+
fn write_space_after_type_to_generic_writer(
1556+
out: &mut impl std::fmt::Write,
1557+
ty: &Type,
1558+
) -> std::fmt::Result {
15271559
match ty {
15281560
Type::Ident(_)
15291561
| Type::RustBox(_)
@@ -1536,7 +1568,7 @@ fn write_space_after_type(out: &mut OutFile, ty: &Type) {
15361568
| Type::SliceRef(_)
15371569
| Type::Fn(_)
15381570
| Type::Array(_) => write!(out, " "),
1539-
Type::Ref(_) | Type::Ptr(_) => {}
1571+
Type::Ref(_) | Type::Ptr(_) => Ok(()),
15401572
Type::Void(_) => unreachable!(),
15411573
}
15421574
}
@@ -1547,7 +1579,10 @@ enum UniquePtr<'a> {
15471579
CxxVector(&'a Ident),
15481580
}
15491581

1582+
// TODO(@anforowicz): Replace `trait ToTypename` with `stringify_type`.
15501583
trait ToTypename {
1584+
/// Formats `self` using C++ syntax. For example, if `self` represents `UniquePtr<u32>`,
1585+
/// then it will be formatted as `::std::unique_ptr<uint32_t>`.
15511586
fn to_typename(&self, types: &Types) -> String;
15521587
}
15531588

0 commit comments

Comments
 (0)