This commit is contained in:
KitsuneCafe 2024-01-30 06:59:27 -05:00
commit 99921e9f2a
6 changed files with 179 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

16
Cargo.lock generated Normal file
View file

@ -0,0 +1,16 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "charon"
version = "0.1.0"
dependencies = [
"streaming-iterator",
]
[[package]]
name = "streaming-iterator"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520"

9
Cargo.toml Normal file
View file

@ -0,0 +1,9 @@
[package]
name = "charon"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
streaming-iterator = "0.1.9"

49
src/lib.rs Normal file
View file

@ -0,0 +1,49 @@
#![feature(bufread_skip_until)]
mod tokenizer;
mod reader;
use std::io::{BufRead, BufReader, Read};
pub struct Attribute<'a> {
pub name: &'a str,
pub value: &'a str,
}
//impl<'a> Attribute<'a> {
// pub fn new(&[u8]) -> Self {
// Self {
//
// }
// }
//}
pub struct Element<'a> {
pub tag: &'a str,
attributes: Vec<Attribute<'a>>,
}
pub enum Node<'a> {
Text(&'a [u8]),
Tag(&'a Element<'a>),
EndTag(&'a Element<'a>),
}
pub struct Charon<R> {
reader: BufReader<R>,
}
impl<R> Charon<R> {
pub fn new(reader: BufReader<R>) -> Self {
Self { reader }
}
}
impl<R: Read> Charon<R> {}
#[cfg(test)]
mod tests {
#[test]
fn reader() {
}
}

82
src/reader.rs Normal file
View file

@ -0,0 +1,82 @@
use std::io::{Read, BufRead};
pub trait Peek {
type Item;
fn peek(&mut self) -> Option<&Self::Item> {
self.peek_n(1)?.first()
}
fn peek_n(&mut self, n: usize) -> Option<&[Self::Item]>;
}
pub struct Reader<R> {
inner: R
}
impl<R> Reader<R> {
pub fn new(inner: R) -> Self {
Self { inner }
}
}
impl<R: BufRead> Peek for Reader<R> {
type Item = u8;
fn peek_n(&mut self, n: usize) -> Option<&[Self::Item]> {
Some(&self.fill_buf().ok()?[..n])
}
}
impl<R: Read> Iterator for Reader<R> {
type Item = u8;
fn next(&mut self) -> Option<Self::Item> {
let mut buf = [0u8];
self.inner.read(&mut buf).ok()?;
Some(buf[0])
}
}
impl<R: Read> Read for Reader<R> {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
self.inner.read(buf)
}
}
impl<R: BufRead> BufRead for Reader<R> {
fn fill_buf(&mut self) -> std::io::Result<&[u8]> {
self.inner.fill_buf()
}
fn consume(&mut self, amt: usize) {
self.inner.consume(amt)
}
}
#[cfg(test)]
mod tests {
use std::io::BufReader;
use crate::reader::Peek;
use super::Reader;
#[test]
fn basic_read() {
let mut reader = Reader::new(BufReader::new(b"this is a test string".as_slice()));
assert_eq!(Some(b't'), reader.next());
assert_eq!(Some(b'h'), reader.next());
assert_eq!(Some(b'i'), reader.next());
assert_eq!(Some(b's'), reader.next());
}
#[test]
fn basic_peek() {
let mut reader = Reader::new(BufReader::new(b"this is a test string".as_slice()));
assert_eq!(Some(&b't'), reader.peek());
assert_eq!(Some(&b't'), reader.peek());
assert_eq!("this", String::from_utf8_lossy(reader.peek_n(4).unwrap()));
assert_eq!("this", String::from_utf8_lossy(reader.peek_n(4).unwrap()));
}
}

22
src/tokenizer.rs Normal file
View file

@ -0,0 +1,22 @@
use std::io::Read;
pub enum Token<'a> {
Space,
TagOpen,
TagClose,
QuoteOpen,
QuoteClose,
Equals,
Tag(&'a str),
Attribute(&'a str),
Value(&'a str)
}
pub struct Tokenizer;
impl Tokenizer {
pub fn parse<R: Read>(reader: R) -> Vec<Token> {
}
}