Update stc library to Rust 2021 edition and update dependencies. Switch from home grown scryfall library to third party one.
This commit is contained in:
parent
b9f3c8f445
commit
3286125d34
@ -2,15 +2,17 @@
|
||||
name="stc"
|
||||
version="0.0.2"
|
||||
authors=["Adrian Malacoda <adrian.malacoda@monarch-pass.net>"]
|
||||
edition="2021"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4.1"
|
||||
env_logger = "0.5.10"
|
||||
sqlite = "0.23.4"
|
||||
select = "0.4.2"
|
||||
reqwest = "0.8.5"
|
||||
reqwest = { version = "0.11.14", features = ["blocking"] }
|
||||
serde_json = "1.0.17"
|
||||
retry = { git = "https://github.com/jimmycuadra/retry", rev = "3fa812e650d64ede61ea243fb83ef1a222ff0f84" }
|
||||
mopa = "0.2.2"
|
||||
linked-hash-map = "0.5.1"
|
||||
scryfall = { git = "http://gitlab.monarch-pass.net/malacoda/scryfall.git" }
|
||||
#scryfall = { git = "https://forge.ds8.zone/beyond/scryfall.git" }
|
||||
scryfall = { git = "https://github.com/adrianmalacoda/scryfall-rs", rev = "e95579e7d9ee1ea7147b72f739f448a7e6dca85a" } # "0.11.1" # for sync api
|
||||
|
6
src/lib.rs
Normal file → Executable file
6
src/lib.rs
Normal file → Executable file
@ -16,12 +16,12 @@ use mopa::Any;
|
||||
pub trait Link: Any {
|
||||
fn label (&self) -> &str;
|
||||
fn url (&self) -> &str;
|
||||
fn as_any(&self) -> &Any;
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
}
|
||||
|
||||
mopafy!(Link);
|
||||
|
||||
impl Link for Box<Link + 'static> {
|
||||
impl Link for Box<dyn Link + 'static> {
|
||||
fn label (&self) -> &str {
|
||||
(**self).label()
|
||||
}
|
||||
@ -30,7 +30,7 @@ impl Link for Box<Link + 'static> {
|
||||
(**self).url()
|
||||
}
|
||||
|
||||
fn as_any (&self) -> &Any {
|
||||
fn as_any (&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
4
src/main.rs
Normal file → Executable file
4
src/main.rs
Normal file → Executable file
@ -2,7 +2,6 @@ extern crate stc;
|
||||
|
||||
use std::env;
|
||||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate env_logger;
|
||||
|
||||
@ -24,12 +23,11 @@ fn main () {
|
||||
|
||||
match searchers.exact_search(&term) {
|
||||
Some(item) => {
|
||||
println!("{}: {}", item.label(), item.url());
|
||||
if let Some(card) = item.downcast_ref::<MtgCard>() {
|
||||
println!("{:?}", card);
|
||||
} else if let Some(card) = item.downcast_ref::<YugiohCard>() {
|
||||
println!("{:?}", card);
|
||||
} else {
|
||||
println!("{}: {}", item.label(), item.url());
|
||||
}
|
||||
},
|
||||
None => println!("not found...")
|
||||
|
22
src/searchers/mediawiki.rs
Normal file → Executable file
22
src/searchers/mediawiki.rs
Normal file → Executable file
@ -1,5 +1,5 @@
|
||||
use Link;
|
||||
use searchers::Searcher;
|
||||
use crate::Link;
|
||||
use crate::searchers::Searcher;
|
||||
|
||||
use reqwest;
|
||||
use reqwest::StatusCode;
|
||||
@ -7,14 +7,11 @@ use reqwest::StatusCode;
|
||||
use select::document::Document;
|
||||
use select::predicate::Name;
|
||||
|
||||
use retry;
|
||||
use retry::retry;
|
||||
use retry::delay::Fixed;
|
||||
|
||||
use std;
|
||||
use std::io::Read;
|
||||
|
||||
//use std::any::Any;
|
||||
use mopa::Any;
|
||||
|
||||
const NUM_RETRIES: usize = 10;
|
||||
@ -35,7 +32,7 @@ impl Link for WikiPage {
|
||||
&self.url
|
||||
}
|
||||
|
||||
fn as_any (&self) -> &Any {
|
||||
fn as_any (&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
@ -52,16 +49,17 @@ impl MediawikiSearcher {
|
||||
}
|
||||
|
||||
fn do_search (&self, name: &str) -> Result<String, Error> {
|
||||
let mut contents = String::new();
|
||||
let api_url = &format!("{}{}", self.baseurl, name);
|
||||
let mut response = retry(Fixed::from_millis(RETRY_WAIT_MILLIS).take(NUM_RETRIES), || {
|
||||
reqwest::get(api_url)
|
||||
let response = retry(Fixed::from_millis(RETRY_WAIT_MILLIS).take(NUM_RETRIES), || {
|
||||
reqwest::blocking::get(api_url)
|
||||
})?;
|
||||
|
||||
match response.status() {
|
||||
StatusCode::Ok => {
|
||||
response.read_to_string(&mut contents)?;
|
||||
Result::Ok(contents)
|
||||
StatusCode::OK => {
|
||||
match response.text() {
|
||||
Ok(text) => Ok(text),
|
||||
Err(error) => Result::Err(Error::Http(error))
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
Result::Err(Error::Other(String::from("Not Found")))
|
||||
|
14
src/searchers/mod.rs
Normal file → Executable file
14
src/searchers/mod.rs
Normal file → Executable file
@ -2,7 +2,7 @@ pub mod mtg;
|
||||
pub mod yugioh;
|
||||
pub mod mediawiki;
|
||||
|
||||
use Link;
|
||||
use crate::Link;
|
||||
use linked_hash_map::LinkedHashMap;
|
||||
|
||||
pub trait Searcher<T: Link> {
|
||||
@ -13,7 +13,7 @@ pub trait Searcher<T: Link> {
|
||||
fn exact_search (&self, name: &str) -> Option<T>;
|
||||
}
|
||||
|
||||
type SearchFn = Box<Fn(String, bool) -> Option<Box<Link>>>;
|
||||
type SearchFn = Box<dyn Fn(String, bool) -> Option<Box<dyn Link>>>;
|
||||
pub struct AggregateSearcher {
|
||||
searchers: LinkedHashMap<String, SearchFn>
|
||||
}
|
||||
@ -25,19 +25,19 @@ impl AggregateSearcher {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_searcher<T: Link + 'static> (&mut self, prefix: &str, searcher: Box<Searcher<T>>) {
|
||||
pub fn add_searcher<T: Link + 'static> (&mut self, prefix: &str, searcher: Box<dyn Searcher<T>>) {
|
||||
let searcher_closure = move |name: String, fuzzy: bool| {
|
||||
(if fuzzy {
|
||||
searcher.fuzzy_search(&name[..])
|
||||
} else {
|
||||
searcher.exact_search(&name[..])
|
||||
}).map(|value| Box::new(value) as Box<Link>)
|
||||
}).map(|value| Box::new(value) as Box<dyn Link>)
|
||||
};
|
||||
|
||||
self.searchers.insert(String::from(prefix), Box::new(searcher_closure));
|
||||
}
|
||||
|
||||
fn run_all_searchers (&self, name: &str) -> Option<Box<Link>> {
|
||||
fn run_all_searchers (&self, name: &str) -> Option<Box<dyn Link>> {
|
||||
for (_, searcher) in &self.searchers {
|
||||
let possible_value = searcher(String::from(name), false);
|
||||
if possible_value.is_some() {
|
||||
@ -49,8 +49,8 @@ impl AggregateSearcher {
|
||||
}
|
||||
}
|
||||
|
||||
impl Searcher<Box<Link>> for AggregateSearcher {
|
||||
fn exact_search (&self, full_name: &str) -> Option<Box<Link>> {
|
||||
impl Searcher<Box<dyn Link>> for AggregateSearcher {
|
||||
fn exact_search (&self, full_name: &str) -> Option<Box<dyn Link>> {
|
||||
match split_prefix(full_name, ":") {
|
||||
Some((prefix, name)) => {
|
||||
self.searchers.get(prefix).and_then(|searcher| searcher(String::from(name), true))
|
||||
|
73
src/searchers/mtg.rs
Normal file → Executable file
73
src/searchers/mtg.rs
Normal file → Executable file
@ -1,19 +1,16 @@
|
||||
use Link;
|
||||
use searchers::Searcher;
|
||||
use crate::Link;
|
||||
use crate::searchers::Searcher;
|
||||
|
||||
use scryfall;
|
||||
use scryfall::{Scryfall, Card};
|
||||
use scryfall::Card;
|
||||
|
||||
use retry;
|
||||
use retry::retry;
|
||||
use retry::delay::Fixed;
|
||||
|
||||
use std;
|
||||
//use retry::retry;
|
||||
//use retry::delay::Fixed;
|
||||
|
||||
use mopa::Any;
|
||||
|
||||
const NUM_RETRIES: usize = 10;
|
||||
const RETRY_WAIT_MILLIS: u64 = 500;
|
||||
// const NUM_RETRIES: usize = 10;
|
||||
// const RETRY_WAIT_MILLIS: u64 = 500;
|
||||
|
||||
pub type MtgCard = Card;
|
||||
|
||||
@ -23,70 +20,24 @@ impl Link for Card {
|
||||
}
|
||||
|
||||
fn url (&self) -> &str {
|
||||
&self.uri
|
||||
self.scryfall_uri.as_str()
|
||||
}
|
||||
|
||||
fn as_any (&self) -> &Any {
|
||||
fn as_any (&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MtgSearcher {
|
||||
scryfall: Scryfall
|
||||
}
|
||||
pub struct MtgSearcher {}
|
||||
|
||||
impl MtgSearcher {
|
||||
pub fn new () -> MtgSearcher{
|
||||
MtgSearcher {
|
||||
scryfall: Scryfall::new()
|
||||
}
|
||||
}
|
||||
|
||||
fn do_search (&self, query: &str) -> Result<Option<Card>, Error> {
|
||||
let mut result = retry(Fixed::from_millis(RETRY_WAIT_MILLIS).take(NUM_RETRIES), || {
|
||||
self.scryfall.search(query, None, 0)
|
||||
})?;
|
||||
|
||||
Ok(if !result.data.is_empty() {
|
||||
Some(result.data.remove(0))
|
||||
} else {
|
||||
None
|
||||
})
|
||||
MtgSearcher {}
|
||||
}
|
||||
}
|
||||
|
||||
impl Searcher<Card> for MtgSearcher {
|
||||
fn exact_search (&self, name: &str) -> Option<Card> {
|
||||
let search = format!(r#"!"{}""#, name);
|
||||
self.do_search(&search).unwrap_or(None)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Error {
|
||||
Client(scryfall::Error),
|
||||
Io(std::io::Error),
|
||||
}
|
||||
|
||||
impl From<scryfall::Error> for Error {
|
||||
fn from (error: scryfall::Error) -> Error {
|
||||
Error::Client(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for Error {
|
||||
fn from (error: std::io::Error) -> Error {
|
||||
Error::Io(error)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl From<retry::Error<scryfall::Error>> for Error {
|
||||
fn from (err: retry::Error<scryfall::Error>) -> Error {
|
||||
match err {
|
||||
retry::Error::Operation { error, total_delay, tries } => {
|
||||
Error::Client(error)
|
||||
}
|
||||
}
|
||||
Card::named(name).ok()
|
||||
}
|
||||
}
|
||||
|
23
src/searchers/yugioh.rs
Normal file → Executable file
23
src/searchers/yugioh.rs
Normal file → Executable file
@ -1,19 +1,14 @@
|
||||
use Link;
|
||||
use searchers::Searcher;
|
||||
use crate::Link;
|
||||
use crate::searchers::Searcher;
|
||||
|
||||
use reqwest;
|
||||
|
||||
use serde_json;
|
||||
use serde_json::Value;
|
||||
|
||||
use retry;
|
||||
use retry::retry;
|
||||
use retry::delay::Fixed;
|
||||
|
||||
use std;
|
||||
use std::io::Read;
|
||||
|
||||
//use std::any::Any;
|
||||
use mopa::Any;
|
||||
|
||||
const NUM_RETRIES: usize = 10;
|
||||
@ -42,7 +37,7 @@ impl Link for YugiohCard {
|
||||
&self.url
|
||||
}
|
||||
|
||||
fn as_any (&self) -> &Any {
|
||||
fn as_any (&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
@ -55,13 +50,15 @@ impl YugiohSearcher {
|
||||
}
|
||||
|
||||
fn do_search (&self, name: &str) -> Result<String, Error> {
|
||||
let mut contents = String::new();
|
||||
let api_url = &format!("http://yugiohprices.com/api/card_data/{}", name);
|
||||
let mut response = retry(Fixed::from_millis(RETRY_WAIT_MILLIS).take(NUM_RETRIES), || {
|
||||
reqwest::get(api_url)
|
||||
let response = retry(Fixed::from_millis(RETRY_WAIT_MILLIS).take(NUM_RETRIES), || {
|
||||
reqwest::blocking::get(api_url)
|
||||
})?;
|
||||
response.read_to_string(&mut contents)?;
|
||||
Result::Ok(contents)
|
||||
|
||||
match response.text() {
|
||||
Ok(text) => Ok(text),
|
||||
Err(error) => Result::Err(Error::Http(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user