generated from musicparty/template
Compare commits
1 Commits
feature/pa
...
1f15e1f31b
| Author | SHA1 | Date | |
|---|---|---|---|
| 1f15e1f31b |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +0,0 @@
|
||||
/target
|
||||
21
Cargo.lock
generated
21
Cargo.lock
generated
@@ -1,21 +0,0 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
|
||||
|
||||
[[package]]
|
||||
name = "apidoc"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"apidoc_parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "apidoc_parser"
|
||||
version = "0.1.0"
|
||||
11
Cargo.toml
11
Cargo.toml
@@ -1,11 +0,0 @@
|
||||
[workspace]
|
||||
resolver = "3"
|
||||
members = ["src/apidoc", "src/apidoc_parser"]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
public = false
|
||||
|
||||
[workspace.clippy]
|
||||
strict = "warn"
|
||||
@@ -1,8 +0,0 @@
|
||||
[package]
|
||||
name = "apidoc"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.100"
|
||||
apidoc_parser = { version = "0.1.0", path = "../apidoc_parser" }
|
||||
@@ -1,17 +0,0 @@
|
||||
use std::{env::args, fs};
|
||||
|
||||
use anyhow::Context;
|
||||
use apidoc_parser::parse;
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
let mut args = args().skip(1);
|
||||
|
||||
let file = fs::read_to_string(args.next().context("expected a file path argument")?)
|
||||
.context("opening file")?;
|
||||
|
||||
println!("{file}");
|
||||
|
||||
parse(file);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
[package]
|
||||
name = "apidoc_parser"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
public.workspace = true
|
||||
|
||||
[dependencies]
|
||||
@@ -1,20 +0,0 @@
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Span {
|
||||
lo: usize,
|
||||
hi: usize,
|
||||
}
|
||||
|
||||
impl Span {
|
||||
pub const fn new(range: std::ops::Range<usize>) -> Self {
|
||||
Self {
|
||||
lo: range.start,
|
||||
hi: range.end,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Comment {
|
||||
pub(crate) prefix: String,
|
||||
pub(crate) span: Span,
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct Cursor {
|
||||
source: String,
|
||||
offset: usize,
|
||||
byte_offset: usize,
|
||||
}
|
||||
|
||||
impl Cursor {
|
||||
pub const fn new(source: String) -> Self {
|
||||
Self {
|
||||
source,
|
||||
offset: 0,
|
||||
byte_offset: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn slice(&self) -> &'_ str {
|
||||
self.source
|
||||
.get(self.byte_offset..)
|
||||
.expect("str should be built out of bounded chars")
|
||||
}
|
||||
|
||||
pub fn bump(&mut self) -> &mut Self {
|
||||
self.offset += 1;
|
||||
self.byte_offset += self.slice().chars().next().map_or(0, char::len_utf8);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn bump_newline(&mut self) -> bool {
|
||||
while !self.slice().starts_with('\n') && !self.bump().is_finished() {}
|
||||
|
||||
if self.slice().starts_with('\n') {
|
||||
self.bump();
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub fn skip(&mut self, chars: usize) {
|
||||
let len: usize = self.slice().chars().take(chars).map(char::len_utf8).sum();
|
||||
|
||||
self.offset += chars;
|
||||
self.byte_offset += len;
|
||||
}
|
||||
|
||||
pub fn skip_whitespace(&mut self) {
|
||||
let mut offset = 0;
|
||||
let mut byte_offset = 0;
|
||||
|
||||
for char in self.slice().chars() {
|
||||
if !char.is_ascii_whitespace() || char == '\n' {
|
||||
break;
|
||||
}
|
||||
|
||||
offset += 1;
|
||||
byte_offset += char.len_utf8();
|
||||
}
|
||||
|
||||
self.offset += offset;
|
||||
self.byte_offset += byte_offset;
|
||||
}
|
||||
|
||||
pub const fn is_finished(&self) -> bool {
|
||||
self.byte_offset >= self.source.len()
|
||||
}
|
||||
|
||||
pub const fn offset(&self) -> usize {
|
||||
self.offset
|
||||
}
|
||||
|
||||
pub fn fmt_offset(&self) -> String {
|
||||
format!("{} (byte {})", self.offset, self.byte_offset)
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
use crate::comment::{Comment, Span};
|
||||
|
||||
pub mod comment;
|
||||
pub(crate) mod cursor;
|
||||
|
||||
use cursor::Cursor;
|
||||
|
||||
// TODO: (issue #3) Move these into some variable configuration
|
||||
const APIDOC_PRAGMA: &str = "@apidoc";
|
||||
const COMMENT_PREFIX: &str = "//";
|
||||
|
||||
pub fn parse(source: String) -> Vec<Comment> {
|
||||
let mut comments = Vec::new();
|
||||
|
||||
let mut cursor = Cursor::new(source);
|
||||
|
||||
while !cursor.bump().is_finished() {
|
||||
let slice = cursor.slice();
|
||||
|
||||
if slice.starts_with(COMMENT_PREFIX) {
|
||||
println!("comment: at offset {}", cursor.fmt_offset());
|
||||
|
||||
let start = cursor.offset();
|
||||
|
||||
cursor.skip(COMMENT_PREFIX.len());
|
||||
cursor.skip_whitespace();
|
||||
if !cursor.slice().starts_with(APIDOC_PRAGMA) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let prefix = COMMENT_PREFIX;
|
||||
|
||||
println!(" pragma! {}", cursor.fmt_offset());
|
||||
|
||||
cursor.bump_newline();
|
||||
let mut end = cursor.offset() - 1;
|
||||
|
||||
loop {
|
||||
cursor.skip_whitespace();
|
||||
if !cursor.slice().starts_with(prefix) {
|
||||
break;
|
||||
}
|
||||
cursor.bump_newline();
|
||||
end = cursor.offset() - 1;
|
||||
}
|
||||
|
||||
comments.push(dbg!(Comment {
|
||||
prefix: COMMENT_PREFIX.to_owned(),
|
||||
span: Span::new(start..end)
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
comments
|
||||
}
|
||||
Reference in New Issue
Block a user