expose headers on Icon
This commit is contained in:
parent
0bead553c2
commit
601d04020c
4 changed files with 26 additions and 12 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -1513,7 +1513,7 @@ checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "site_icons"
|
name = "site_icons"
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"clap",
|
"clap",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "site_icons"
|
name = "site_icons"
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
authors = ["Sam Denty <sam@samdenty.com>"]
|
authors = ["Sam Denty <sam@samdenty.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
|
|
|
@ -2,6 +2,7 @@ use super::IconInfo;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::{
|
use std::{
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
|
collections::HashMap,
|
||||||
fmt::{self, Display},
|
fmt::{self, Display},
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
};
|
};
|
||||||
|
@ -40,6 +41,7 @@ impl FromStr for IconKind {
|
||||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
|
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
pub struct Icon {
|
pub struct Icon {
|
||||||
pub url: Url,
|
pub url: Url,
|
||||||
|
pub headers: HashMap<String, String>,
|
||||||
#[serde(with = "serde_with::rust::display_fromstr")]
|
#[serde(with = "serde_with::rust::display_fromstr")]
|
||||||
pub kind: IconKind,
|
pub kind: IconKind,
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
|
|
32
src/icons.rs
32
src/icons.rs
|
@ -9,6 +9,7 @@ use html5ever::{
|
||||||
use reqwest::{header::*, IntoUrl};
|
use reqwest::{header::*, IntoUrl};
|
||||||
use scraper::{ElementRef, Html};
|
use scraper::{ElementRef, Html};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
use std::convert::TryInto;
|
||||||
use std::task::Poll;
|
use std::task::Poll;
|
||||||
use std::{collections::HashMap, error::Error, pin::Pin, task::Context};
|
use std::{collections::HashMap, error::Error, pin::Pin, task::Context};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
@ -19,6 +20,7 @@ pub struct Icons {
|
||||||
Url,
|
Url,
|
||||||
(
|
(
|
||||||
IconKind,
|
IconKind,
|
||||||
|
HashMap<String, String>,
|
||||||
Pin<Box<dyn Future<Output = Result<IconInfo, Box<dyn Error>>>>>,
|
Pin<Box<dyn Future<Output = Result<IconInfo, Box<dyn Error>>>>>,
|
||||||
),
|
),
|
||||||
>,
|
>,
|
||||||
|
@ -27,11 +29,17 @@ pub struct Icons {
|
||||||
fn add_icon_entry(
|
fn add_icon_entry(
|
||||||
entries: &mut Vec<Icon>,
|
entries: &mut Vec<Icon>,
|
||||||
url: Url,
|
url: Url,
|
||||||
|
headers: HashMap<String, String>,
|
||||||
kind: IconKind,
|
kind: IconKind,
|
||||||
info: Result<IconInfo, Box<dyn Error>>,
|
info: Result<IconInfo, Box<dyn Error>>,
|
||||||
) {
|
) {
|
||||||
match info {
|
match info {
|
||||||
Ok(info) => entries.push(Icon { url, kind, info }),
|
Ok(info) => entries.push(Icon {
|
||||||
|
url,
|
||||||
|
headers,
|
||||||
|
kind,
|
||||||
|
info,
|
||||||
|
}),
|
||||||
Err(_) => warn_err!(info, "failed to parse icon"),
|
Err(_) => warn_err!(info, "failed to parse icon"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +54,7 @@ impl Icons {
|
||||||
|
|
||||||
/// Add an icon URL and start fetching it
|
/// Add an icon URL and start fetching it
|
||||||
pub fn add_icon(&mut self, url: Url, kind: IconKind, sizes: Option<String>) {
|
pub fn add_icon(&mut self, url: Url, kind: IconKind, sizes: Option<String>) {
|
||||||
self.add_icon_with_headers(url, HeaderMap::new(), kind, sizes)
|
self.add_icon_with_headers(url, HashMap::new(), kind, sizes)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add an icon URL and start fetching it,
|
/// Add an icon URL and start fetching it,
|
||||||
|
@ -54,7 +62,7 @@ impl Icons {
|
||||||
pub fn add_icon_with_headers(
|
pub fn add_icon_with_headers(
|
||||||
&mut self,
|
&mut self,
|
||||||
url: Url,
|
url: Url,
|
||||||
headers: HeaderMap,
|
headers: HashMap<String, String>,
|
||||||
kind: IconKind,
|
kind: IconKind,
|
||||||
sizes: Option<String>,
|
sizes: Option<String>,
|
||||||
) {
|
) {
|
||||||
|
@ -63,7 +71,7 @@ impl Icons {
|
||||||
if let Some(existing_kind) = self
|
if let Some(existing_kind) = self
|
||||||
.pending_entries
|
.pending_entries
|
||||||
.get_mut(&url)
|
.get_mut(&url)
|
||||||
.map(|(kind, _)| kind)
|
.map(|(kind, _, _)| kind)
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
entries.find_map(|icon| {
|
entries.find_map(|icon| {
|
||||||
if icon.url.eq(&url) {
|
if icon.url.eq(&url) {
|
||||||
|
@ -81,15 +89,19 @@ impl Icons {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut info = Box::pin(IconInfo::load(url.clone(), headers, sizes));
|
let mut info = Box::pin(IconInfo::load(
|
||||||
|
url.clone(),
|
||||||
|
(&headers).try_into().unwrap(),
|
||||||
|
sizes,
|
||||||
|
));
|
||||||
|
|
||||||
// Start fetching the icon
|
// Start fetching the icon
|
||||||
let noop_waker = noop_waker();
|
let noop_waker = noop_waker();
|
||||||
let cx = &mut Context::from_waker(&noop_waker);
|
let cx = &mut Context::from_waker(&noop_waker);
|
||||||
match info.poll_unpin(cx) {
|
match info.poll_unpin(cx) {
|
||||||
Poll::Ready(info) => add_icon_entry(&mut self.entries, url, kind, info),
|
Poll::Ready(info) => add_icon_entry(&mut self.entries, url, headers, kind, info),
|
||||||
Poll::Pending => {
|
Poll::Pending => {
|
||||||
self.pending_entries.insert(url, (kind, info));
|
self.pending_entries.insert(url, (kind, headers, info));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -278,14 +290,14 @@ impl Icons {
|
||||||
let (urls, infos): (Vec<_>, Vec<_>) = self
|
let (urls, infos): (Vec<_>, Vec<_>) = self
|
||||||
.pending_entries
|
.pending_entries
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(url, (kind, info))| ((url, kind), info))
|
.map(|(url, (kind, headers, info))| ((url, headers, kind), info))
|
||||||
.unzip();
|
.unzip();
|
||||||
|
|
||||||
let mut urls = urls.into_iter();
|
let mut urls = urls.into_iter();
|
||||||
|
|
||||||
for info in join_all(infos).await {
|
for info in join_all(infos).await {
|
||||||
let (url, kind) = urls.next().unwrap();
|
let (url, headers, kind) = urls.next().unwrap();
|
||||||
add_icon_entry(&mut self.entries, url, kind, info);
|
add_icon_entry(&mut self.entries, url, headers, kind, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.entries.sort();
|
self.entries.sort();
|
||||||
|
|
Reference in a new issue