Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Enhancement] rs2md: Outsource Logic to Dedicated Struct #997

Merged
merged 8 commits into from
Dec 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
(
references: {},
changes: {
"Added": [
"Rs2md",
"src/utilities.rs",
"tests/utilities.rs",
"tests/assets/gpl-3.0-inner.rs",
"tests/assets/gpl-3.0-outer.rs",
],
"Changed": [
"rs2md: outsource logic to dedicated struct",
],
},
)
47 changes: 2 additions & 45 deletions src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,25 +85,7 @@ pub enum Action {
Ronlog(crate::Ronlog),

/// Extract Markdown code from Rust documentation comments.
Rs2md {
/// Whether to extract Rust documentation comments starting with `///`.
#[arg(long = "inner")]
extract_inner: bool,

/// Whether to extract Rust documentation comments starting with `//!`.
#[arg(long = "outer")]
extract_outer: bool,

/// The Rust files to read from, defaulting to [`std::io::Stdin`], if
/// omitted.
#[arg(long = "input", short)]
input_file: Vec<PathBuf>,

/// The Markdown file to write to, defaulting to [`std::io::Stdout`], if
/// omitted.
#[arg(long = "output", short)]
output_file: Option<PathBuf>,
},
Rs2md(crate::Rs2md),

/// Remove CRLFs from the given file.
Uncrlf {
Expand All @@ -122,23 +104,6 @@ pub enum Action {
}

impl Action {
fn rs2md(s: &str, extract_inner: bool, extract_outer: bool) -> String {
s.lines()
.map(str::trim_start)
.filter(|l| {
(extract_inner && l.starts_with("///"))
|| (extract_outer && l.starts_with("//!"))
})
.map(|l| {
if l.len() > 3 {
l.split_at(4).1.trim_end().to_string() + "\n"
} else {
"\n".to_string()
}
})
.collect::<String>()
}

/// Execute the selected action.
///
/// # Errors
Expand Down Expand Up @@ -196,15 +161,7 @@ impl Action {
+ "\", }, ], \"settings\" : [], }\n",
)),
Self::Ronlog(r) => r.main(),
Self::Rs2md {
extract_inner,
extract_outer,
input_file,
output_file,
} => (|s: String| -> String {
Self::rs2md(&s, *extract_inner, *extract_outer)
})
.io(input_file, output_file),
Self::Rs2md(r) => r.main(),
Self::Uncrlf {
file_to_edit,
input_file,
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,7 @@ mod macros;
mod pattern;
mod running;
mod traits;
mod utilities;
mod version;

pub use crate::{
Expand All @@ -474,6 +475,7 @@ pub use crate::{
AppendAsLine, ColourMessage, ConvertBuffer, FromMd, FromRon, FromRst,
FromXml, Prefer, ReadFile, ToMd, ToRon, ToRst, ToStderr, ToXml,
},
utilities::Rs2md,
version::{Range as VersionRange, Version},
};

Expand Down
101 changes: 101 additions & 0 deletions src/utilities.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*********************** GNU General Public License 3.0 ***********************\
| |
| Copyright (C) 2023 Kevin Matthes |
| |
| This program is free software: you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation, either version 3 of the License, or |
| (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program. If not, see <https://www.gnu.org/licenses/>. |
| |
\******************************************************************************/

use crate::PatternIOProcessor;
use std::path::PathBuf;
use sysexits::Result;

/// Extract Markdown code from Rust documentation comments.
#[derive(clap::Parser, Clone)]
pub struct Rs2md {
/// Whether to extract Rust documentation comments starting with `///`.
#[arg(long = "inner")]
extract_inner: bool,

/// Whether to extract Rust documentation comments starting with `//!`.
#[arg(long = "outer")]
extract_outer: bool,

/// The Rust files to read from, defaulting to [`std::io::Stdin`], if
/// omitted.
#[arg(long = "input", short)]
input_file: Vec<PathBuf>,

/// The Markdown file to write to, defaulting to [`std::io::Stdout`], if
/// omitted.
#[arg(long = "output", short)]
output_file: Option<PathBuf>,
}

impl Rs2md {
/// Extract Markdown code from Rust documentation comments.
///
/// # Errors
///
/// See
///
/// - [`PatternIOProcessor::io`]
pub fn main(&self) -> Result<()> {
(|s: String| {
s.lines()
.map(str::trim_start)
.filter(|l| {
(self.extract_inner && l.starts_with("///"))
|| (self.extract_outer && l.starts_with("//!"))
})
.map(|l| {
if l.len() > 3 {
l.split_at(4).1.trim_end().to_string() + "\n"
} else {
"\n".to_string()
}
})
.collect::<String>()
})
.io(&self.input_file, &self.output_file)
}

/// Create a new instance.
pub fn new<T>(
input_file: Vec<T>,
output_file: Option<T>,
extract_inner: bool,
extract_outer: bool,
) -> Self
where
PathBuf: From<T>,
{
Self {
extract_inner,
extract_outer,
input_file: {
let mut i = Vec::new();

for file in input_file {
i.push(file.into());
}

i
},
output_file: output_file.map(Into::into),
}
}
}

/******************************************************************************/
14 changes: 14 additions & 0 deletions tests/assets/gpl-3.0-inner.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/// Copyright (C) 2023 Kevin Matthes
///
/// This program is free software: you can redistribute it and/or modify
/// it under the terms of the GNU General Public License as published by
/// the Free Software Foundation, either version 3 of the License, or
/// (at your option) any later version.
///
/// This program is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU General Public License for more details.
///
/// You should have received a copy of the GNU General Public License
/// along with this program. If not, see <https://www.gnu.org/licenses/>.
14 changes: 14 additions & 0 deletions tests/assets/gpl-3.0-outer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//! Copyright (C) 2023 Kevin Matthes
//!
//! This program is free software: you can redistribute it and/or modify
//! it under the terms of the GNU General Public License as published by
//! the Free Software Foundation, either version 3 of the License, or
//! (at your option) any later version.
//!
//! This program is distributed in the hope that it will be useful,
//! but WITHOUT ANY WARRANTY; without even the implied warranty of
//! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//! GNU General Public License for more details.
//!
//! You should have received a copy of the GNU General Public License
//! along with this program. If not, see <https://www.gnu.org/licenses/>.
156 changes: 156 additions & 0 deletions tests/utilities.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/*********************** GNU General Public License 3.0 ***********************\
| |
| Copyright (C) 2023 Kevin Matthes |
| |
| This program is free software: you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation, either version 3 of the License, or |
| (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program. If not, see <https://www.gnu.org/licenses/>. |
| |
\******************************************************************************/

use aeruginous::{ReadFile, Rs2md};
use std::fs::remove_file;

macro_rules! make_test {
( @rs2md @none $( $n:ident -> $i:expr , $o:expr ),+ ) => {
$(
#[test]
fn $n() {
assert!(Rs2md::new(
vec![
"tests/assets/gpl-3.0-inner.rs",
"tests/assets/gpl-3.0-outer.rs"
],
Some(concat!(stringify!($n), ".md")),
$i,
$o
).main().is_ok());

assert!(
concat!(stringify!($n), ".md")
.read()
.unwrap()
.is_empty()
);

remove_file(concat!(stringify!($n), ".md")).unwrap();
}
)+
};

( @rs2md @once $( $n:ident -> $i:expr , $o:expr ),+ ) => {
$(
#[test]
fn $n() {
assert!(Rs2md::new(
vec![
"tests/assets/gpl-3.0-inner.rs",
"tests/assets/gpl-3.0-outer.rs"
],
Some(concat!(stringify!($n), ".md")),
$i,
$o
).main().is_ok());

assert_eq!(
concat!(stringify!($n), ".md").read().unwrap(),
"\
Copyright (C) 2023 Kevin Matthes

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"
);

remove_file(concat!(stringify!($n), ".md")).unwrap();
}
)+
};

( @rs2md @twice $( $n:ident -> $i:expr , $o:expr ),+ ) => {
$(
#[test]
fn $n() {
assert!(Rs2md::new(
vec![
"tests/assets/gpl-3.0-inner.rs",
"tests/assets/gpl-3.0-outer.rs"
],
Some(concat!(stringify!($n), ".md")),
$i,
$o
).main().is_ok());

assert_eq!(
concat!(stringify!($n), ".md").read().unwrap(),
"\
Copyright (C) 2023 Kevin Matthes

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Copyright (C) 2023 Kevin Matthes

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"
);

remove_file(concat!(stringify!($n), ".md")).unwrap();
}
)+
};
}

make_test!(@rs2md @none
rs2md_neither_inner_nor_outer -> false, false
);

make_test!(@rs2md @once
rs2md_only_inner -> true, false,
rs2md_only_outer -> false, true
);

make_test!(@rs2md @twice
rs2md_both_inner_and_outer -> true, true
);

/******************************************************************************/