initial
This commit is contained in:
commit
99921e9f2a
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target
|
16
Cargo.lock
generated
Normal file
16
Cargo.lock
generated
Normal 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
9
Cargo.toml
Normal 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
49
src/lib.rs
Normal 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
82
src/reader.rs
Normal 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
22
src/tokenizer.rs
Normal 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> {
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in a new issue