init
This commit is contained in:
commit
2cb99526c7
|
@ -0,0 +1,2 @@
|
|||
/target
|
||||
Cargo.lock
|
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "slipper"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
cursive = "0.20.0"
|
||||
select = "0.6.0"
|
|
@ -0,0 +1,47 @@
|
|||
pub struct Entry {
|
||||
title: String,
|
||||
url: String,
|
||||
score: usize,
|
||||
}
|
||||
|
||||
//use select::predicate::{Attr, Class, Name, Predicate};
|
||||
use select::predicate::*;
|
||||
|
||||
impl Entry {
|
||||
pub fn new(node: &select::node::Node) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
Ok(Self {
|
||||
title: node
|
||||
.find(Class("u-url"))
|
||||
.next()
|
||||
.ok_or("Couldn't find title")?
|
||||
.inner_html(),
|
||||
url: node
|
||||
.find(Class("u-url"))
|
||||
.next()
|
||||
.ok_or("couldn't find url")?
|
||||
.attr("href")
|
||||
.ok_or("invalid url href")?
|
||||
.to_owned(),
|
||||
score: node
|
||||
.find(Class("score"))
|
||||
.next()
|
||||
.ok_or("couldn't find score")?
|
||||
.inner_html()
|
||||
.parse::<usize>()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Entry {
|
||||
pub fn title(&self) -> &str {
|
||||
&self.title
|
||||
}
|
||||
|
||||
pub fn url(&self) -> &str {
|
||||
&self.url
|
||||
}
|
||||
|
||||
pub fn score(&self) -> usize {
|
||||
self.score
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
#![allow(unused_imports)]
|
||||
|
||||
use select::document::Document;
|
||||
use select::predicate::{Attr, Class, Name, Predicate};
|
||||
|
||||
mod entry;
|
||||
use entry::Entry;
|
||||
|
||||
fn fetch_frontpage_entries() -> Result<Vec<Entry>, Box<dyn std::error::Error>> {
|
||||
let document = Document::from(include_str!("index.html"));
|
||||
|
||||
let entries = document
|
||||
.find(Class("story"))
|
||||
.map(|n| Entry::new(&n).unwrap())
|
||||
.collect::<Vec<Entry>>();
|
||||
|
||||
Ok(entries)
|
||||
}
|
||||
|
||||
use cursive::traits::*;
|
||||
use cursive::views::{Button, Dialog, DummyView, LinearLayout, SelectView};
|
||||
use cursive::Cursive;
|
||||
|
||||
pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut siv = cursive::default();
|
||||
|
||||
let select = SelectView::<String>::new()
|
||||
.with_name("select")
|
||||
.fixed_size((80u8, 40u8));
|
||||
let buttons = LinearLayout::vertical()
|
||||
//.child(Button::new("Add new", add_name))
|
||||
//.child(Button::new("Delete", delete_name))
|
||||
.child(DummyView)
|
||||
.child(Button::new("Quit", Cursive::quit));
|
||||
|
||||
siv.add_layer(
|
||||
Dialog::around(
|
||||
LinearLayout::horizontal()
|
||||
.child(select)
|
||||
.child(DummyView)
|
||||
.child(buttons),
|
||||
)
|
||||
.title("Select a profile"),
|
||||
);
|
||||
|
||||
for e in fetch_frontpage_entries()? {
|
||||
siv.call_on_name("select", |view: &mut SelectView<String>| {
|
||||
view.add_item_str(e.title());
|
||||
});
|
||||
}
|
||||
|
||||
siv.run();
|
||||
|
||||
Ok(())
|
||||
}
|
Reference in New Issue