cl-repl: Add example that prints the AST in a more friendly way than Debug
but in a more verbose way than Display
This commit is contained in:
parent
2cdf112aa6
commit
9f9a21b4c3
653
cl-repl/examples/yaml.rs
Normal file
653
cl-repl/examples/yaml.rs
Normal file
@ -0,0 +1,653 @@
|
|||||||
|
//! Pretty prints a conlang AST in yaml
|
||||||
|
|
||||||
|
use cl_lexer::Lexer;
|
||||||
|
use cl_parser::Parser;
|
||||||
|
use cl_repl::repline::{error::Error as RlError, Repline};
|
||||||
|
use std::error::Error;
|
||||||
|
|
||||||
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
let mut rl = Repline::new("\x1b[33m", "cl>", "? >");
|
||||||
|
loop {
|
||||||
|
let line = match rl.read() {
|
||||||
|
Err(RlError::CtrlC(_)) => break,
|
||||||
|
Err(RlError::CtrlD(line)) => {
|
||||||
|
rl.deny();
|
||||||
|
line
|
||||||
|
}
|
||||||
|
Ok(line) => line,
|
||||||
|
Err(e) => Err(e)?,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut parser = Parser::new(Lexer::new(&line));
|
||||||
|
let code = match parser.stmt() {
|
||||||
|
Ok(code) => {
|
||||||
|
rl.accept();
|
||||||
|
code
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
print!("\x1b[40G\x1bJ\x1b[91m{e}\x1b[0m");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
print!("\x1b[G\x1b[J\x1b[A");
|
||||||
|
Yamler::new().yaml(&code);
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub use yamler::Yamler;
|
||||||
|
pub mod yamler {
|
||||||
|
use crate::yamlify::Yamlify;
|
||||||
|
use std::{
|
||||||
|
fmt::Display,
|
||||||
|
io::Write,
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
|
};
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct Yamler {
|
||||||
|
depth: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Yamler {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn indent(&mut self) -> Section {
|
||||||
|
Section::new(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Prints a [Yamlify] value
|
||||||
|
#[inline]
|
||||||
|
pub fn yaml<T: Yamlify>(&mut self, yaml: &T) -> &mut Self {
|
||||||
|
yaml.yaml(self);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn increase(&mut self) {
|
||||||
|
self.depth += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decrease(&mut self) {
|
||||||
|
self.depth -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_indentation(&self, writer: &mut impl Write) {
|
||||||
|
for _ in 0..self.depth {
|
||||||
|
let _ = write!(writer, " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Prints a section header and increases indentation
|
||||||
|
pub fn key(&mut self, name: impl Display) -> Section {
|
||||||
|
println!();
|
||||||
|
self.print_indentation(&mut std::io::stdout().lock());
|
||||||
|
print!("- {name}:");
|
||||||
|
self.indent()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Prints a yaml key value pair: `- name: "value"`
|
||||||
|
pub fn pair<D: Display, T: Yamlify>(&mut self, name: D, value: T) -> &mut Self {
|
||||||
|
self.key(name).yaml(&value);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Prints a yaml scalar value: `"name"``
|
||||||
|
pub fn value<D: Display>(&mut self, value: D) -> &mut Self {
|
||||||
|
print!(" {value}");
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn list<D: Yamlify>(&mut self, list: &[D]) -> &mut Self {
|
||||||
|
for (idx, value) in list.iter().enumerate() {
|
||||||
|
self.pair(idx, value);
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Tracks the start and end of an indented block (a "section")
|
||||||
|
pub struct Section<'y> {
|
||||||
|
yamler: &'y mut Yamler,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'y> Section<'y> {
|
||||||
|
pub fn new(yamler: &'y mut Yamler) -> Self {
|
||||||
|
yamler.increase();
|
||||||
|
Self { yamler }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'y> Deref for Section<'y> {
|
||||||
|
type Target = Yamler;
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
self.yamler
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'y> DerefMut for Section<'y> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
self.yamler
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'y> Drop for Section<'y> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let Self { yamler } = self;
|
||||||
|
yamler.decrease();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod yamlify {
|
||||||
|
use super::yamler::Yamler;
|
||||||
|
use cl_ast::*;
|
||||||
|
|
||||||
|
pub trait Yamlify {
|
||||||
|
fn yaml(&self, y: &mut Yamler);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Yamlify for File {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let File { items } = self;
|
||||||
|
y.key("File").yaml(items);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Visibility {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
if let Visibility::Public = self {
|
||||||
|
y.pair("vis", "pub");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Mutability {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
if let Mutability::Mut = self {
|
||||||
|
y.pair("mut", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Yamlify for Attrs {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { meta } = self;
|
||||||
|
y.key("Attrs").yaml(meta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Meta {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { name, kind } = self;
|
||||||
|
y.key("Meta").pair("name", name).yaml(kind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for MetaKind {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
match self {
|
||||||
|
MetaKind::Plain => y,
|
||||||
|
MetaKind::Equals(value) => y.pair("equals", value),
|
||||||
|
MetaKind::Func(args) => y.pair("args", args),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Yamlify for Item {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { extents: _, attrs, vis, kind } = self;
|
||||||
|
y.key("Item").yaml(attrs).yaml(vis).yaml(kind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for ItemKind {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
match self {
|
||||||
|
ItemKind::Alias(f) => y.yaml(f),
|
||||||
|
ItemKind::Const(f) => y.yaml(f),
|
||||||
|
ItemKind::Static(f) => y.yaml(f),
|
||||||
|
ItemKind::Module(f) => y.yaml(f),
|
||||||
|
ItemKind::Function(f) => y.yaml(f),
|
||||||
|
ItemKind::Struct(f) => y.yaml(f),
|
||||||
|
ItemKind::Enum(f) => y.yaml(f),
|
||||||
|
ItemKind::Impl(f) => y.yaml(f),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Alias {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { to, from } = self;
|
||||||
|
y.key("Alias").pair("to", to).pair("from", from);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Const {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { name, ty, init } = self;
|
||||||
|
y.key("Const")
|
||||||
|
.pair("name", name)
|
||||||
|
.pair("ty", ty)
|
||||||
|
.pair("init", init);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Static {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { mutable, name, ty, init } = self;
|
||||||
|
y.key(name).yaml(mutable).pair("ty", ty).pair("init", init);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Module {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { name, kind } = self;
|
||||||
|
y.key("Module").pair("name", name).yaml(kind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for ModuleKind {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
match self {
|
||||||
|
ModuleKind::Inline(f) => y.yaml(f),
|
||||||
|
ModuleKind::Outline => y,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Function {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { name, args, body, rety } = self;
|
||||||
|
y.key("Function")
|
||||||
|
.pair("name", name)
|
||||||
|
.pair("args", args)
|
||||||
|
.pair("body", body)
|
||||||
|
.pair("rety", rety);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Struct {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { name, kind } = self;
|
||||||
|
y.key("Struct").pair("name", name).yaml(kind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for StructKind {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
match self {
|
||||||
|
StructKind::Empty => y,
|
||||||
|
StructKind::Tuple(k) => y.yaml(k),
|
||||||
|
StructKind::Struct(k) => y.yaml(k),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for StructMember {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { vis, name, ty } = self;
|
||||||
|
y.key("StructMember").yaml(vis).pair("name", name).yaml(ty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Enum {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { name, kind } = self;
|
||||||
|
y.key("Enum").pair("name", name).yaml(kind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for EnumKind {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
match self {
|
||||||
|
EnumKind::NoVariants => y,
|
||||||
|
EnumKind::Variants(v) => y.yaml(v),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Variant {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { name, kind } = self;
|
||||||
|
y.key("Variant").pair("name", name).yaml(kind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for VariantKind {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
match self {
|
||||||
|
VariantKind::Plain => y,
|
||||||
|
VariantKind::CLike(v) => y.yaml(v),
|
||||||
|
VariantKind::Tuple(v) => y.yaml(v),
|
||||||
|
VariantKind::Struct(v) => y.yaml(v),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Impl {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { target, body } = self;
|
||||||
|
y.key("Impl").pair("target", target).pair("body", body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Block {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { stmts } = self;
|
||||||
|
y.key("Block").yaml(stmts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Stmt {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { extents: _, kind, semi } = self;
|
||||||
|
y.key("Stmt").yaml(kind).yaml(semi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Semi {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
if let Semi::Terminated = self {
|
||||||
|
y.pair("terminated", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for StmtKind {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
match self {
|
||||||
|
StmtKind::Empty => y,
|
||||||
|
StmtKind::Local(s) => y.yaml(s),
|
||||||
|
StmtKind::Item(s) => y.yaml(s),
|
||||||
|
StmtKind::Expr(s) => y.yaml(s),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Let {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { mutable, name, ty, init } = self;
|
||||||
|
y.key("Let")
|
||||||
|
.pair("name", name)
|
||||||
|
.yaml(mutable)
|
||||||
|
.pair("ty", ty)
|
||||||
|
.pair("init", init);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Expr {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { extents: _, kind } = self;
|
||||||
|
y.yaml(kind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for ExprKind {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
match self {
|
||||||
|
ExprKind::Assign(k) => k.yaml(y),
|
||||||
|
ExprKind::Binary(k) => k.yaml(y),
|
||||||
|
ExprKind::Unary(k) => k.yaml(y),
|
||||||
|
ExprKind::Member(k) => k.yaml(y),
|
||||||
|
ExprKind::Call(k) => k.yaml(y),
|
||||||
|
ExprKind::Index(k) => k.yaml(y),
|
||||||
|
ExprKind::Path(k) => k.yaml(y),
|
||||||
|
ExprKind::Literal(k) => k.yaml(y),
|
||||||
|
ExprKind::Array(k) => k.yaml(y),
|
||||||
|
ExprKind::ArrayRep(k) => k.yaml(y),
|
||||||
|
ExprKind::AddrOf(k) => k.yaml(y),
|
||||||
|
ExprKind::Block(k) => k.yaml(y),
|
||||||
|
ExprKind::Empty => {}
|
||||||
|
ExprKind::Group(k) => k.yaml(y),
|
||||||
|
ExprKind::Tuple(k) => k.yaml(y),
|
||||||
|
ExprKind::While(k) => k.yaml(y),
|
||||||
|
ExprKind::If(k) => k.yaml(y),
|
||||||
|
ExprKind::For(k) => k.yaml(y),
|
||||||
|
ExprKind::Break(k) => k.yaml(y),
|
||||||
|
ExprKind::Return(k) => k.yaml(y),
|
||||||
|
ExprKind::Continue(k) => k.yaml(y),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Assign {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { head, op: _, tail } = self;
|
||||||
|
y.key("Assign").pair("head", head).pair("tail", tail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Binary {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { head, tail } = self;
|
||||||
|
let mut y = y.key("Binary");
|
||||||
|
y.pair("head", head);
|
||||||
|
for (op, expr) in tail {
|
||||||
|
y.key("tail").pair("op", op).pair("expr", expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for BinaryKind {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
y.value(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Unary {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { ops, tail } = self;
|
||||||
|
let mut y = y.key("Unary");
|
||||||
|
for op in ops {
|
||||||
|
y.pair("op", op);
|
||||||
|
}
|
||||||
|
y.pair("tail", tail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for UnaryKind {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
y.value(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Member {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { head, tail } = self;
|
||||||
|
y.key("Member").pair("head", head).pair("tail", tail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Call {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { callee, args } = self;
|
||||||
|
y.key("Call").pair("callee", callee).pair("args", args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Tuple {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { exprs } = self;
|
||||||
|
y.key("Tuple").list(exprs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Index {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { head, indices } = self;
|
||||||
|
y.key("Index").pair("head", head).list(indices);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Indices {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { exprs } = self;
|
||||||
|
y.key("Indices").list(exprs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Array {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { values } = self;
|
||||||
|
y.key("Array").list(values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for ArrayRep {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { value, repeat } = self;
|
||||||
|
y.key("ArrayRep")
|
||||||
|
.pair("value", value)
|
||||||
|
.pair("repeat", repeat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for AddrOf {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { count: _, mutable, expr } = self;
|
||||||
|
y.key("Addr").yaml(mutable).pair("expr", expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Group {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { expr } = self;
|
||||||
|
y.key("Group").yaml(expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for While {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { cond, pass, fail } = self;
|
||||||
|
y.key("While")
|
||||||
|
.pair("cond", cond)
|
||||||
|
.pair("pass", pass)
|
||||||
|
.pair("fail", fail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Else {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { body } = self;
|
||||||
|
y.key("Else").yaml(body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for If {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { cond, pass, fail } = self;
|
||||||
|
y.key("If").pair("cond", cond).pair("pass", pass).yaml(fail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for For {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { bind, cond, pass, fail } = self;
|
||||||
|
y.key("For")
|
||||||
|
.pair("bind", bind)
|
||||||
|
.pair("cond", cond)
|
||||||
|
.pair("pass", pass)
|
||||||
|
.yaml(fail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Break {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { body } = self;
|
||||||
|
y.key("Break").yaml(body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Return {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { body } = self;
|
||||||
|
y.key("Return").yaml(body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Continue {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
y.key("Continue");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Literal {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
y.value(format_args!("\"{self}\""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Identifier {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self(name) = self;
|
||||||
|
y.value(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Param {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { mutability, name, ty } = self;
|
||||||
|
y.key("Param")
|
||||||
|
.yaml(mutability)
|
||||||
|
.pair("name", name)
|
||||||
|
.pair("ty", ty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Ty {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { extents: _, kind } = self;
|
||||||
|
y.key("Ty").yaml(kind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for TyKind {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
match self {
|
||||||
|
TyKind::Never => y.value("Never"),
|
||||||
|
TyKind::Empty => y.value("Empty"),
|
||||||
|
TyKind::SelfTy => y.value("Self"),
|
||||||
|
TyKind::Path(t) => y.yaml(t),
|
||||||
|
TyKind::Tuple(t) => y.yaml(t),
|
||||||
|
TyKind::Ref(t) => y.yaml(t),
|
||||||
|
TyKind::Fn(t) => y.yaml(t),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for Path {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { absolute, parts } = self;
|
||||||
|
let mut y = y.key("Path");
|
||||||
|
if *absolute {
|
||||||
|
y.pair("absolute", absolute);
|
||||||
|
}
|
||||||
|
for part in parts {
|
||||||
|
y.pair("part", part);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for PathPart {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
match self {
|
||||||
|
PathPart::SuperKw => y.value("super"),
|
||||||
|
PathPart::SelfKw => y.value("self"),
|
||||||
|
PathPart::Ident(i) => y.yaml(i),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for TyTuple {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { types } = self;
|
||||||
|
let mut y = y.key("TyTuple");
|
||||||
|
for ty in types {
|
||||||
|
y.yaml(ty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for TyRef {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { count, to } = self;
|
||||||
|
y.key("TyRef").pair("count", count).pair("to", to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for TyFn {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { args, rety } = self;
|
||||||
|
y.key("TyFn").pair("args", args).pair("rety", rety);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Yamlify> Yamlify for Option<T> {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
if let Some(v) = self {
|
||||||
|
y.yaml(v);
|
||||||
|
} else {
|
||||||
|
y.value("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<T: Yamlify> Yamlify for Box<T> {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
y.yaml(&**self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<T: Yamlify> Yamlify for Vec<T> {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
for thing in self {
|
||||||
|
y.yaml(thing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Yamlify for () {
|
||||||
|
fn yaml(&self, _y: &mut Yamler) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Yamlify> Yamlify for &T {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
(*self).yaml(y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! scalar {
|
||||||
|
($($t:ty),*$(,)?) => {
|
||||||
|
$(impl Yamlify for $t {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
y.value(self);
|
||||||
|
}
|
||||||
|
})*
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
scalar! {
|
||||||
|
bool, char, u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, &str, String
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user