add the selector and the request base

master
kirbylife 2021-01-17 20:01:06 -06:00
parent 78e0c40cd6
commit 78bd9af763
5 changed files with 129 additions and 3 deletions

View File

@ -1,9 +1,14 @@
[package]
name = "raspa"
version = "0.1.0"
authors = ["kirbylife <gabriel13m@gmail.com>"]
authors = ["kirbylife <kirbylife@protonmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
reqwest = { version = "0.10", features = ["blocking", "json"] }
tokio = { version = "0.2", features = ["full"] }
url = "2.1"
http = "0.2"
nipper = "0.1.8"

View File

@ -1,7 +1,34 @@
pub mod request;
pub mod response;
pub mod selector;
#[cfg(test)]
mod tests {
use crate::request::{Request, RequestBase};
use crate::selector::{Selector, SelectorBase};
use http::StatusCode;
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
fn plain_text_selector() {
let html = "
<html>
<body>
<h1>hello world</h1>
<p id='text'>good bye</p>
</body>
</html>
";
let sel = Selector::from_html(html);
println!("{:?}", sel.css("h1"));
assert_eq!(sel.css("h1")[0].html(), "<h1>hello world</h1>");
assert_eq!(sel.css("#text")[0].content(), "good bye");
}
#[test]
fn simple_request() {
let req: Request = RequestBase::new("https://httpbin.org/");
let resp = req.launch();
assert_eq!(resp.status_code, StatusCode::OK);
assert!(resp.css("h2")[0].html().contains("httpbin.org"));
}
}

36
src/request.rs 100644
View File

@ -0,0 +1,36 @@
use crate::response;
use http::status::StatusCode;
use url::Url;
pub trait RequestBase {
fn new(url: &'static str) -> Self;
fn launch(&self) -> response::Response;
}
#[derive(Debug)]
pub struct Request {
pub url: url::Url,
}
impl RequestBase for Request {
fn new(url: &'static str) -> Request {
Request {
url: Url::parse(url).unwrap(),
}
}
fn launch(&self) -> response::Response {
let resp = reqwest::blocking::get(self.url.as_str()).unwrap();
let text: String = resp.text().unwrap();
let status = StatusCode::OK;
let url = self.url.clone();
response::Response {
text: text,
status_code: status,
url: url,
}
}
}

16
src/response.rs 100644
View File

@ -0,0 +1,16 @@
use crate::selector::SelectorBase;
use http::StatusCode;
use url::Url;
#[derive(Debug)]
pub struct Response {
pub text: String,
pub status_code: StatusCode,
pub url: Url,
}
impl SelectorBase for Response {
fn html(&self) -> &str {
self.text.as_str()
}
}

42
src/selector.rs 100644
View File

@ -0,0 +1,42 @@
pub trait SelectorBase {
fn html(&self) -> &str;
fn css(&self, css_selector: &'static str) -> Vec<Selector> {
let html = nipper::Document::from(self.html());
html.select(css_selector)
.iter()
.map(|element| Selector {
text: element.html().to_string(),
})
.into_iter()
.collect::<Vec<_>>()
}
fn content(&self) -> String {
let html = nipper::Document::from(self.html());
html.select("*")
.iter()
.map(|element| element.text().to_string())
.last()
.unwrap()
}
}
#[derive(Debug)]
pub struct Selector {
text: String,
}
impl SelectorBase for Selector {
fn html(&self) -> &str {
self.text.as_str()
}
}
impl Selector {
pub fn from_html(html: &'static str) -> Self {
Selector {
text: html.to_string(),
}
}
}