Skip to content

Commit

Permalink
chore!: separate vimdoc from parser (#42)
Browse files Browse the repository at this point in the history
Resolves #41
  • Loading branch information
numToStr authored Sep 27, 2022
1 parent 15d02b1 commit f98322f
Show file tree
Hide file tree
Showing 30 changed files with 573 additions and 446 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ jobs:

- name: Test
shell: bash
run: ${{ env.CARGO }} test --target=${{ matrix.job.target }}
run: ${{ env.CARGO }} test --features=vimdoc --target=${{ matrix.job.target }}

- name: Package
shell: bash
Expand Down
20 changes: 5 additions & 15 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,13 @@ required-features = ["cli"]

[dependencies]
chumsky = { version = "0.8.0", default-features = false }

[dependencies.textwrap]
version = "0.15.1"
default-features = false
# optional = true

[dependencies.comfy-table]
version = "6.1.0"
default-features = false
# optional = true

[dependencies.lexopt]
version = "0.2.1"
optional = true
textwrap = { version = "0.15.1", default-features = false, optional = true }
comfy-table = { version = "6.1.0", default-features = false, optional = true }
lexopt = { version = "0.2.1", default-features = false, optional = true }

[features]
cli = ["dep:lexopt"]
vimdoc = ["dep:textwrap", "dep:comfy-table"]
cli = ["vimdoc", "dep:lexopt"]

[profile.release]
lto = true
Expand Down
5 changes: 3 additions & 2 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use lemmy_help::{LemmyHelp, Rename};
use lemmy_help::{vimdoc::VimDoc, FromEmmy, LemmyHelp, Rename};

use lexopt::{
Arg::{Long, Short, Value},
Parser,
Expand Down Expand Up @@ -73,7 +74,7 @@ impl Cli {
lemmy.for_help(&source).unwrap();
}

print!("{lemmy}");
print!("{}", VimDoc::from_emmy(&lemmy, ()));

if self.modeline {
println!("vim:tw=78:ts=8:noet:ft=help:norl:");
Expand Down
76 changes: 36 additions & 40 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
#[cfg(feature = "vimdoc")]
pub mod vimdoc;

pub mod lexer;
pub mod parser;

use chumsky::prelude::Simple;
use parser::{Module, Node};
use std::fmt::Display;

use chumsky::prelude::Simple;
use parser::Node;

use crate::lexer::TagType;

pub trait Nodes {
fn nodes(&self) -> &Vec<Node>;
}

pub trait FromEmmy: Display {
type Settings;
fn from_emmy(t: &impl Nodes, s: Self::Settings) -> Self;
}

pub trait AsDoc<T: FromEmmy> {
fn as_doc(&self, s: T::Settings) -> T;
}

#[derive(Debug, Default)]
pub struct Rename {
/// Prefix `function` name with `---@mod` name
Expand All @@ -22,7 +39,19 @@ pub struct Rename {
#[derive(Debug, Default)]
pub struct LemmyHelp {
rename: Rename,
pub nodes: Vec<Node>,
nodes: Vec<Node>,
}

impl Nodes for LemmyHelp {
fn nodes(&self) -> &Vec<Node> {
&self.nodes
}
}

impl<T: FromEmmy> AsDoc<T> for LemmyHelp {
fn as_doc(&self, s: T::Settings) -> T {
T::from_emmy(self, s)
}
}

impl LemmyHelp {
Expand All @@ -43,7 +72,9 @@ impl LemmyHelp {
/// Parse given lua source code to generate AST representation
///
/// ```
/// let mut lemmy = lemmy_help::LemmyHelp::default();
/// use lemmy_help::{LemmyHelp, Nodes};
///
/// let mut lemmy = LemmyHelp::default();
/// let src = r#"
/// local U = {}
///
Expand All @@ -58,7 +89,7 @@ impl LemmyHelp {
/// "#;
///
/// let ast = lemmy.parse(&src).unwrap();
/// assert!(!ast.nodes.is_empty());
/// assert!(!ast.nodes().is_empty());
/// ```
pub fn parse(&mut self, src: &str) -> Result<&Self, Vec<Simple<TagType>>> {
self.nodes.append(&mut Node::new(src)?);
Expand Down Expand Up @@ -115,38 +146,3 @@ impl LemmyHelp {
Ok(self)
}
}

impl Display for LemmyHelp {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for node in &self.nodes {
if let Node::Toc(x) = node {
writeln!(
f,
"{}",
Module {
name: x.to_string(),
desc: Some("Table of Contents".into()),
}
)?;

for nodde in &self.nodes {
if let Node::Module(x) = nodde {
let desc = x.desc.as_deref().unwrap_or_default();

writeln!(
f,
"{desc}{}",
format_args!("{:·>w$}", format!("|{}|", x.name), w = 80 - desc.len())
)?;
}
}

writeln!(f)?;
} else {
writeln!(f, "{node}")?;
}
}

Ok(())
}
}
21 changes: 19 additions & 2 deletions src/parser.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
mod util;
pub(super) use util::*;
mod node;
pub use node::*;
mod tags;
pub use tags::*;

macro_rules! impl_parse {
($id: ident, $ret: ty, $body: expr) => {
impl $id {
pub fn parse() -> impl chumsky::Parser<
$crate::lexer::TagType,
$ret,
Error = chumsky::prelude::Simple<$crate::lexer::TagType>,
> {
$body
}
}
};
($id: ident, $body: expr) => {
crate::parser::impl_parse!($id, Self, $body);
};
}

pub(super) use impl_parse;
18 changes: 0 additions & 18 deletions src/parser/node.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::fmt::Display;

use chumsky::{
prelude::{any, choice, Simple},
select, Parser, Stream,
Expand Down Expand Up @@ -73,19 +71,3 @@ impl Node {
Node::parse().repeated().flatten().parse(stream)
}
}

impl Display for Node {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match &self {
Self::Brief(x) => x.fmt(f),
Self::Tag(x) => x.fmt(f),
Self::Func(x) => x.fmt(f),
Self::Class(x) => x.fmt(f),
Self::Alias(x) => x.fmt(f),
Self::Type(x) => x.fmt(f),
Self::Module(x) => x.fmt(f),
Self::Divider(x) => x.fmt(f),
_ => unimplemented!(),
}
}
}
39 changes: 1 addition & 38 deletions src/parser/tags/alias.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
use std::fmt::Display;

use chumsky::{prelude::choice, select, Parser};

use crate::{
lexer::TagType,
parser::{description, header, impl_parse, Prefix, Table},
parser::{impl_parse, Prefix},
};

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -51,38 +49,3 @@ impl Alias {
self.prefix.right = Some(tag);
}
}

impl Display for Alias {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(prefix) = &self.prefix.right {
header!(f, &self.name, format!("{prefix}.{}", self.name))?;
} else {
header!(f, &self.name)?;
}

if !self.desc.is_empty() {
crate::parser::description!(f, &self.desc.join("\n"))?;
}

writeln!(f)?;

match &self.kind {
AliasKind::Type(ty) => {
description!(f, "Type: ~")?;
writeln!(f, "{:>w$}", ty, w = 8 + ty.len())?;
}
AliasKind::Enum(variants) => {
description!(f, "Variants: ~")?;

let mut table = Table::new();
for (ty, desc) in variants {
table.add_row([&format!("({})", ty), desc.as_deref().unwrap_or_default()]);
}

f.write_str(&table.to_string())?;
}
}

writeln!(f)
}
}
8 changes: 0 additions & 8 deletions src/parser/tags/brief.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::fmt::Display;

use chumsky::{prelude::just, select, Parser};

use crate::{lexer::TagType, parser::impl_parse};
Expand All @@ -17,9 +15,3 @@ impl_parse!(Brief, {
.delimited_by(just(TagType::BriefStart), just(TagType::BriefEnd))
.map(|desc| Self { desc })
});

impl Display for Brief {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "{}", self.desc.join("\n"))
}
}
43 changes: 1 addition & 42 deletions src/parser/tags/class.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
use std::fmt::Display;

use chumsky::{select, Parser};

use crate::{
lexer::{Scope, TagType},
parser::{description, header, impl_parse, Prefix, See, Table},
parser::{impl_parse, Prefix, See},
};

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -67,42 +65,3 @@ impl Class {
self.prefix.right = Some(tag);
}
}

impl Display for Class {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(prefix) = &self.prefix.right {
header!(f, &self.name, format!("{prefix}.{}", self.name))?;
} else {
header!(f, &self.name)?;
}

if !self.desc.is_empty() {
description!(f, &self.desc.join("\n"))?;
}
writeln!(f)?;

if !self.fields.is_empty() {
description!(f, "Fields: ~")?;

let mut table = Table::new();

for field in &self.fields {
if field.scope == Scope::Public {
table.add_row([
&format!("{{{}}}", field.name),
&format!("({})", field.ty),
&field.desc.join("\n"),
]);
}
}

writeln!(f, "{table}")?;
}

if !self.see.refs.is_empty() {
writeln!(f, "{}", self.see)?;
}

Ok(())
}
}
8 changes: 0 additions & 8 deletions src/parser/tags/divider.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::fmt::Display;

use chumsky::select;

use crate::{lexer::TagType, parser::impl_parse};
Expand All @@ -10,9 +8,3 @@ pub struct Divider(pub char);
impl_parse!(Divider, {
select! { TagType::Divider(rune) => Self(rune) }
});

impl Display for Divider {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "{}", self.0.to_string().repeat(80))
}
}
Loading

0 comments on commit f98322f

Please sign in to comment.