refactor: make serde optional and fix clippy warnings

This commit is contained in:
Anna 2019-04-04 18:58:06 -04:00
parent df28d5c014
commit 18895752aa
22 changed files with 120 additions and 89 deletions

View File

@ -6,7 +6,7 @@ authors = ["Kyle Clemens <git@kyleclemens.com>"]
edition = "2018"
[features]
default = ["logic"]
default = ["logic", "with_serde"]
logic = [
"cssparser",
@ -14,23 +14,37 @@ logic = [
"lazy_static",
"scraper",
]
with_serde = [
"serde",
"serde_derive",
"url_serde",
]
[dependencies]
cssparser = { version = "0.24", optional = true }
failure = { version = "0.1", optional = true }
lazy_static = { version = "1", optional = true }
scraper = { version = "0.9", optional = true }
serde = "1"
serde_derive = "1"
serde_json = "1"
serde = { version = "1", optional = true }
serde_derive = { version = "1", optional = true }
url = "1"
url_serde = "0.2"
url_serde = { version = "0.2", optional = true }
[dependencies.chrono]
# with serde
[target.'cfg(feature = "with_serde")'.dependencies.chrono]
version = "0.4"
features = ["serde"]
[dependencies.ffxiv_types]
[target.'cfg(feature = "with_serde")'.dependencies.ffxiv_types]
version = "1"
default-features = false
features = ["worlds", "races", "clans", "guardians", "with_serde"]
# without serde
[target.'cfg(not(feature = "with_serde"))'.dependencies.chrono]
version = "0.4"
[target.'cfg(not(feature = "with_serde"))'.dependencies.ffxiv_types]
version = "1"
default-features = false
features = ["worlds", "races", "clans", "guardians"]

View File

@ -20,7 +20,7 @@ pub enum Error {
impl Error {
pub fn missing_element(select: &scraper::Selector) -> Self {
use cssparser::ToCss;
let css = select.selectors.iter().map(|x| x.to_css_string()).collect::<Vec<_>>().join(" ");
let css = select.selectors.iter().map(ToCss::to_css_string).collect::<Vec<_>>().join(" ");
Error::MissingElement(css)
}

View File

@ -1,9 +1,7 @@
#![feature(crate_visibility_modifier)]
#![allow(clippy::unreadable_literal)]
#[cfg(feature = "logic")] extern crate failure;
#[cfg(feature = "logic")] #[macro_use] extern crate lazy_static;
pub extern crate ffxiv_types;
#[macro_use] extern crate serde_derive;
#[cfg(feature = "logic")]
pub mod error;

View File

@ -14,6 +14,8 @@ use scraper::{
macro_rules! selectors {
($($name:ident => $selector:expr);+$(;)?) => {
use lazy_static::lazy_static;
lazy_static! {
$(
static ref $name: scraper::Selector = scraper::Selector::parse($selector).unwrap();
@ -38,7 +40,7 @@ crate fn plain_parse(html: &Html, select: &scraper::Selector) -> Result<String>
let string = html
.select(select)
.next()
.ok_or(Error::missing_element(select))?
.ok_or_else(|| Error::missing_element(select))?
.text()
.collect();
Ok(string)
@ -48,13 +50,13 @@ crate fn plain_parse_elem<'a>(html: ElementRef<'a>, select: &scraper::Selector)
let string = html
.select(select)
.next()
.ok_or(Error::missing_element(select))?
.ok_or_else(|| Error::missing_element(select))?
.text()
.collect();
Ok(string)
}
crate fn parse_id<'a>(a: &'a Element) -> Result<u64> {
crate fn parse_id(a: &Element) -> Result<u64> {
let href = a.attr("href").ok_or_else(|| Error::invalid_content("href on link", None))?;
let last = href
.split('/')

View File

@ -135,7 +135,7 @@ fn parse_rcg(html: &Html) -> Result<(Race, Clan, Gender)> {
fn parse_guardian(html: &Html) -> Result<Guardian> {
let guardian_str = plain_parse(&html, &*PROFILE_GUARDIAN)?;
guardian_str
.split(",")
.split(',')
.next()
.ok_or_else(|| Error::invalid_content("first part of guardian", Some(&guardian_str)))
.and_then(|x| Guardian::from_str(&x)
@ -206,7 +206,7 @@ fn parse_jobs(html: &Html) -> Result<BTreeMap<Job, JobInfo>> {
Ok(jobs)
}
fn parse_job<'a>(elem: ElementRef<'a>) -> Result<(Job, JobInfo)> {
fn parse_job(elem: ElementRef) -> Result<(Job, JobInfo)> {
let job = crate::logic::plain_parse_elem(elem, &*CLASS_NAME)
.and_then(|x| Job::parse(&x).ok_or_else(|| Error::invalid_content("valid job", Some(&x))))?;

View File

@ -97,11 +97,11 @@ fn parse_pvp_rank(html: &Html, select: &scraper::Selector) -> Result<Option<u64>
let rank_str = plain_parse(html, select)?;
let rank = rank_str
.split(":")
.split(':')
.nth(1)
.ok_or_else(|| Error::invalid_content("colon-separated text", Some(&rank_str)))
.and_then(|x| x
.split(" ")
.split(' ')
.next()
.ok_or_else(|| Error::invalid_content("space-separated text", Some(&rank_str))))?;
@ -119,16 +119,16 @@ fn parse_formed(html: &Html) -> Result<DateTime<Utc>> {
let script = html
.select(&*FC_FORMED)
.next()
.ok_or(Error::missing_element(&*FC_FORMED))?
.ok_or_else(|| Error::missing_element(&*FC_FORMED))?
.inner_html();
let timestamp = script
.split("strftime(")
.nth(1)
.ok_or(Error::invalid_content("strftime call", Some(&script)))?
.split(",")
.ok_or_else(|| Error::invalid_content("strftime call", Some(&script)))?
.split(',')
.next()
.ok_or(Error::invalid_content("comma-separated strftime call", Some(&script)))?;
.ok_or_else(|| Error::invalid_content("comma-separated strftime call", Some(&script)))?;
let timestamp: i64 = timestamp.parse().map_err(Error::InvalidNumber)?;
let utc = Local.timestamp(timestamp, 0).with_timezone(&Utc);
@ -154,7 +154,6 @@ fn parse_estate(html: &Html) -> Result<Option<Estate>> {
fn parse_crest(html: &Html) -> Result<Vec<Url>> {
html.select(&*FC_CREST)
.into_iter()
.filter_map(|x| x.value().attr("src"))
.map(|x| Url::parse(x).map_err(Error::InvalidUrl))
.collect()
@ -173,7 +172,7 @@ fn parse_grand_company(html: &Html) -> Result<GrandCompany> {
fn parse_reputation(html: &Html) -> Result<BTreeMap<GrandCompany, u8>> {
let mut reps = BTreeMap::new();
for elem in html.select(&*FC_REPUTATION).into_iter() {
for elem in html.select(&*FC_REPUTATION) {
let name: String = elem
.select(&*FC_REPUTATION_NAME)
.next()

View File

@ -63,7 +63,7 @@ fn parse_members(html_str: &str) -> Result<Paginated<LinkshellMember>> {
let results: Vec<LinkshellMember> = html
.select(&*ITEM_ENTRY)
.map(|x| parse_single(x))
.map(parse_single)
.collect::<Result<_>>()?;
Ok(Paginated {
@ -72,8 +72,7 @@ fn parse_members(html_str: &str) -> Result<Paginated<LinkshellMember>> {
})
}
fn parse_single<'a>(html: ElementRef<'a>) -> Result<LinkshellMember> {
fn parse_single(html: ElementRef) -> Result<LinkshellMember> {
let character = super::search::character::parse_single(html)?;
let role = parse_role(html)?;
@ -84,7 +83,7 @@ fn parse_single<'a>(html: ElementRef<'a>) -> Result<LinkshellMember> {
})
}
fn parse_role<'a>(html: ElementRef<'a>) -> Result<Option<Role>> {
fn parse_role(html: ElementRef) -> Result<Option<Role>> {
let role = match html.select(&*ITEM_ROLE).next() {
Some(r) => r,
None => return Ok(None),
@ -104,6 +103,7 @@ mod test {
};
use super::parse;
use lazy_static::lazy_static;
use ffxiv_types::World;
lazy_static! {

View File

@ -66,7 +66,7 @@ crate fn parse_pagination(html: &Html) -> Result<Pagination> {
})
}
crate fn parse_no_results<'a>(html: &Html) -> bool {
crate fn parse_no_results(html: &Html) -> bool {
html.select(&*NO_RESULTS)
.next()
.map(|x| x.text().collect::<String>() == "Your search yielded no results.")

View File

@ -41,7 +41,7 @@ pub fn parse(html: &str) -> Result<Paginated<CharacterSearchItem>> {
let results: Vec<CharacterSearchItem> = html
.select(&*ITEM_ENTRY)
.map(|x| parse_single(x))
.map(parse_single)
.collect::<Result<_>>()?;
Ok(Paginated {
@ -50,7 +50,7 @@ pub fn parse(html: &str) -> Result<Paginated<CharacterSearchItem>> {
})
}
crate fn parse_single<'a>(html: ElementRef<'a>) -> Result<CharacterSearchItem> {
crate fn parse_single(html: ElementRef) -> Result<CharacterSearchItem> {
let id = parse_id(html)?;
let name = plain_parse(html, &*ITEM_NAME)?;
@ -72,7 +72,7 @@ crate fn parse_single<'a>(html: ElementRef<'a>) -> Result<CharacterSearchItem> {
})
}
fn parse_id<'a>(html: ElementRef<'a>) -> Result<u64> {
fn parse_id(html: ElementRef) -> Result<u64> {
let e = html
.select(&*ITEM_ID)
.next()
@ -80,13 +80,13 @@ fn parse_id<'a>(html: ElementRef<'a>) -> Result<u64> {
crate::logic::parse_id(e.value())
}
fn parse_world<'a>(html: ElementRef<'a>) -> Result<World> {
fn parse_world(html: ElementRef) -> Result<World> {
let world_str = plain_parse(html, &*ITEM_WORLD)?;
World::from_str(&world_str)
.map_err(|_| Error::invalid_content("valid world", Some(&world_str)))
}
fn parse_free_company_id<'a>(html: ElementRef<'a>) -> Result<Option<u64>> {
fn parse_free_company_id(html: ElementRef) -> Result<Option<u64>> {
let elem = match html
.select(&*ITEM_FREE_COMPANY)
.next()
@ -97,7 +97,7 @@ fn parse_free_company_id<'a>(html: ElementRef<'a>) -> Result<Option<u64>> {
crate::logic::parse_id(elem.value()).map(Some)
}
fn parse_grand_company<'a>(html: ElementRef<'a>) -> Result<Option<GrandCompanyInfo>> {
fn parse_grand_company(html: ElementRef) -> Result<Option<GrandCompanyInfo>> {
let text = html
.select(&*ITEM_GRAND_COMPANY)
.next()
@ -109,7 +109,7 @@ fn parse_grand_company<'a>(html: ElementRef<'a>) -> Result<Option<GrandCompanyIn
crate::logic::parse_grand_company(text).map(Some)
}
fn parse_face<'a>(html: ElementRef<'a>) -> Result<Url> {
fn parse_face(html: ElementRef) -> Result<Url> {
let face_elem = html
.select(&*ITEM_FACE)
.next()

View File

@ -47,7 +47,7 @@ pub fn parse(s: &str) -> Result<Paginated<FreeCompanySearchItem>> {
let results: Vec<FreeCompanySearchItem> = html
.select(&*ITEM_ENTRY)
.map(|x| parse_single(x))
.map(parse_single)
.collect::<Result<_>>()?;
Ok(Paginated {
@ -56,7 +56,7 @@ pub fn parse(s: &str) -> Result<Paginated<FreeCompanySearchItem>> {
})
}
fn parse_single<'a>(html: ElementRef<'a>) -> Result<FreeCompanySearchItem> {
fn parse_single(html: ElementRef) -> Result<FreeCompanySearchItem> {
let id = parse_id(html)?;
let grand_company = parse_grand_company(html)?;
let name = plain_parse(html, &*ITEM_NAME)?;
@ -82,7 +82,7 @@ fn parse_single<'a>(html: ElementRef<'a>) -> Result<FreeCompanySearchItem> {
})
}
fn parse_id<'a>(html: ElementRef<'a>) -> Result<u64> {
fn parse_id(html: ElementRef) -> Result<u64> {
let e = html
.select(&*ITEM_ID)
.next()
@ -90,31 +90,31 @@ fn parse_id<'a>(html: ElementRef<'a>) -> Result<u64> {
crate::logic::parse_id(e.value())
}
fn parse_grand_company<'a>(html: ElementRef<'a>) -> Result<GrandCompany> {
fn parse_grand_company(html: ElementRef) -> Result<GrandCompany> {
let gc_str = plain_parse(html, &*ITEM_GRAND_COMPANY)?;
GrandCompany::parse(&gc_str)
.ok_or_else(|| Error::invalid_content("valid grand company", Some(&gc_str)))
}
fn parse_world<'a>(html: ElementRef<'a>) -> Result<World> {
fn parse_world(html: ElementRef) -> Result<World> {
let world_str = plain_parse(html, &*ITEM_WORLD)?;
World::from_str(&world_str)
.map_err(|_| Error::invalid_content("valid world", Some(&world_str)))
}
fn parse_crest<'a>(html: ElementRef<'a>) -> Result<Vec<Url>> {
fn parse_crest(html: ElementRef) -> Result<Vec<Url>> {
html.select(&*ITEM_CREST)
.filter_map(|x| x.value().attr("src"))
.map(|x| Url::from_str(x).map_err(Error::InvalidUrl))
.collect()
}
fn parse_active_members<'a>(html: ElementRef<'a>) -> Result<u16> {
fn parse_active_members(html: ElementRef) -> Result<u16> {
plain_parse(html, &*ITEM_ACTIVE_MEMBERS)
.and_then(|x| x.parse().map_err(Error::InvalidNumber))
}
fn parse_estate_built<'a>(html: ElementRef<'a>) -> Result<bool> {
fn parse_estate_built(html: ElementRef) -> Result<bool> {
let estate_built = plain_parse(html, &*ITEM_ESTATE_BUILT)?;
let built = match estate_built.as_str() {
"Estate Built" => true,
@ -125,20 +125,20 @@ fn parse_estate_built<'a>(html: ElementRef<'a>) -> Result<bool> {
Ok(built)
}
fn parse_formed<'a>(html: ElementRef<'a>) -> Result<DateTime<Utc>> {
fn parse_formed(html: ElementRef) -> Result<DateTime<Utc>> {
let script = html
.select(&*ITEM_FORMED)
.next()
.ok_or(Error::missing_element(&*ITEM_FORMED))?
.ok_or_else(|| Error::missing_element(&*ITEM_FORMED))?
.inner_html();
let timestamp = script
.split("strftime(")
.nth(1)
.ok_or(Error::invalid_content("strftime call", Some(&script)))?
.split(",")
.ok_or_else(|| Error::invalid_content("strftime call", Some(&script)))?
.split(',')
.next()
.ok_or(Error::invalid_content("comma-separated strftime call", Some(&script)))?;
.ok_or_else(|| Error::invalid_content("comma-separated strftime call", Some(&script)))?;
let timestamp: i64 = timestamp.parse().map_err(Error::InvalidNumber)?;
let utc = Local.timestamp(timestamp, 0).with_timezone(&Utc);
@ -146,7 +146,7 @@ fn parse_formed<'a>(html: ElementRef<'a>) -> Result<DateTime<Utc>> {
Ok(utc)
}
fn parse_active<'a>(html: ElementRef<'a>) -> Result<Active> {
fn parse_active(html: ElementRef) -> Result<Active> {
plain_parse(html, &*ITEM_ACTIVE)
.and_then(|x| x
.split(": ")
@ -157,7 +157,7 @@ fn parse_active<'a>(html: ElementRef<'a>) -> Result<Active> {
.ok_or_else(|| Error::invalid_content("valid activity", Some(&x))))
}
fn parse_recruitment<'a>(html: ElementRef<'a>) -> Result<RecruitmentStatus> {
fn parse_recruitment(html: ElementRef) -> Result<RecruitmentStatus> {
plain_parse(html, &*ITEM_RECRUITMENT)
.and_then(|x| x
.split(": ")

View File

@ -36,7 +36,7 @@ pub fn parse(s: &str) -> Result<Paginated<LinkshellSearchItem>> {
let results: Vec<LinkshellSearchItem> = html
.select(&*ITEM_ENTRY)
.map(|x| parse_single(x))
.map(parse_single)
.collect::<Result<_>>()?;
Ok(Paginated {
@ -45,7 +45,7 @@ pub fn parse(s: &str) -> Result<Paginated<LinkshellSearchItem>> {
})
}
fn parse_single<'a>(html: ElementRef<'a>) -> Result<LinkshellSearchItem> {
fn parse_single(html: ElementRef) -> Result<LinkshellSearchItem> {
let id = parse_id(html)?;
let name = plain_parse(html, &*ITEM_NAME)?;
let world = parse_world(html)?;
@ -59,7 +59,7 @@ fn parse_single<'a>(html: ElementRef<'a>) -> Result<LinkshellSearchItem> {
})
}
fn parse_id<'a>(html: ElementRef<'a>) -> Result<u64> {
fn parse_id(html: ElementRef) -> Result<u64> {
let e = html
.select(&*ITEM_ID)
.next()
@ -67,13 +67,13 @@ fn parse_id<'a>(html: ElementRef<'a>) -> Result<u64> {
crate::logic::parse_id(e.value())
}
fn parse_world<'a>(html: ElementRef<'a>) -> Result<World> {
fn parse_world(html: ElementRef) -> Result<World> {
let world_str = plain_parse(html, &*ITEM_WORLD)?;
World::from_str(&world_str)
.map_err(|_| Error::invalid_content("valid world", Some(&world_str)))
}
fn parse_active_members<'a>(html: ElementRef<'a>) -> Result<u8> {
fn parse_active_members(html: ElementRef) -> Result<u8> {
plain_parse(html, &*ITEM_ACTIVE_MEMBERS)
.and_then(|x| x.parse().map_err(Error::InvalidNumber))
}

View File

@ -1,7 +1,8 @@
macro_rules! ffxiv_enum {
($(#[$meta:meta])* $name:ident { $($variant:ident => $str_repr:expr),+$(,)? }) => {
$(#[$meta])*
#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)]
#[derive(Debug, PartialEq, Clone, Copy)]
#[cfg_attr(feature = "with_serde", derive(serde_derive::Serialize, serde_derive::Deserialize))]
pub enum $name {
$($variant,)+
}

View File

@ -1,12 +1,12 @@
use super::GrandCompany;
#[cfg(feature = "with_serde")] use serde_derive::{Deserialize, Serialize};
use ffxiv_types::{World, Race, Clan, Guardian};
use url::Url;
use std::collections::BTreeMap;
#[derive(Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "with_serde", derive(Deserialize, Serialize))]
pub struct Character {
pub id: u64,
@ -22,26 +22,28 @@ pub struct Character {
pub city_state: CityState,
pub grand_company: Option<GrandCompanyInfo>,
#[serde(with = "crate::util::serde::opt_u64_str")]
#[cfg_attr(feature = "with_serde", serde(with = "crate::util::serde::opt_u64_str"))]
pub free_company_id: Option<u64>,
pub profile_text: String,
pub jobs: BTreeMap<Job, JobInfo>,
#[serde(with = "url_serde")]
#[cfg_attr(feature = "with_serde", serde(with = "url_serde"))]
pub face: Url,
#[serde(with = "url_serde")]
#[cfg_attr(feature = "with_serde", serde(with = "url_serde"))]
pub portrait: Url,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[derive(Debug, PartialEq)]
#[cfg_attr(feature = "with_serde", derive(Deserialize, Serialize))]
pub struct GrandCompanyInfo {
pub name: GrandCompany,
pub rank: String,
}
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug)]
#[cfg_attr(feature = "with_serde", derive(Deserialize, Serialize))]
pub struct JobInfo {
pub level: Option<u8>,
pub experience: Option<u64>,

View File

@ -1,21 +1,21 @@
use super::GrandCompany;
use chrono::{DateTime, Utc};
use ffxiv_types::World;
#[cfg(feature = "with_serde")] use serde_derive::{Deserialize, Serialize};
use url::Url;
use std::collections::BTreeMap;
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug)]
#[cfg_attr(feature = "with_serde", derive(Deserialize, Serialize))]
pub struct FreeCompany {
#[serde(with = "crate::util::serde::u64_str")]
#[cfg_attr(feature = "with_serde", serde(with = "crate::util::serde::u64_str"))]
pub id: u64,
pub name: String,
pub world: World,
pub slogan: String,
#[serde(with = "crate::util::serde::multi_url")]
#[cfg_attr(feature = "with_serde", serde(with = "crate::util::serde::multi_url"))]
pub crest: Vec<Url>,
pub grand_company: GrandCompany,
pub active_members: u16,
@ -26,13 +26,15 @@ pub struct FreeCompany {
pub reputation: BTreeMap<GrandCompany, u8>,
}
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug)]
#[cfg_attr(feature = "with_serde", derive(Deserialize, Serialize))]
pub struct PvpRankings {
pub weekly: Option<u64>,
pub monthly: Option<u64>,
}
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug)]
#[cfg_attr(feature = "with_serde", derive(Deserialize, Serialize))]
pub struct Estate {
pub name: String,
pub address: String,

View File

@ -1,10 +1,12 @@
use super::search::{Paginated, character::CharacterSearchItem};
use ffxiv_types::World;
#[cfg(feature = "with_serde")] use serde_derive::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug)]
#[cfg_attr(feature = "with_serde", derive(Deserialize, Serialize))]
pub struct Linkshell {
#[serde(with = "crate::util::serde::u64_str")]
#[cfg_attr(feature = "with_serde", serde(with = "crate::util::serde::u64_str"))]
pub id: u64,
pub name: String,
pub world: World,
@ -12,9 +14,10 @@ pub struct Linkshell {
pub members: Paginated<LinkshellMember>,
}
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug)]
#[cfg_attr(feature = "with_serde", derive(Deserialize, Serialize))]
pub struct LinkshellMember {
#[serde(flatten)]
#[cfg_attr(feature = "with_serde", serde(flatten))]
pub character: CharacterSearchItem,
pub role: Option<Role>,
}

View File

@ -1,15 +1,19 @@
#[cfg(feature = "with_serde")] use serde_derive::{Deserialize, Serialize};
pub mod character;
pub mod free_company;
pub mod linkshell;
#[derive(Debug, Default, Serialize, Deserialize)]
#[derive(Debug, Default)]
#[cfg_attr(feature = "with_serde", derive(Deserialize, Serialize))]
pub struct Pagination {
pub current_page: u64,
pub total_pages: u64,
pub total_results: u64,
}
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug)]
#[cfg_attr(feature = "with_serde", derive(Deserialize, Serialize))]
pub struct Paginated<T> {
pub pagination: Pagination,
pub results: Vec<T>,

View File

@ -1,17 +1,19 @@
use crate::models::character::GrandCompanyInfo;
use ffxiv_types::World;
#[cfg(feature = "with_serde")] use serde_derive::{Deserialize, Serialize};
use url::Url;
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug)]
#[cfg_attr(feature = "with_serde", derive(Deserialize, Serialize))]
pub struct CharacterSearchItem {
pub id: u64,
pub name: String,
pub world: World,
pub grand_company: Option<GrandCompanyInfo>,
#[serde(with = "crate::util::serde::opt_u64_str")]
#[cfg_attr(feature = "with_serde", serde(with = "crate::util::serde::opt_u64_str"))]
pub free_company_id: Option<u64>,
#[serde(with = "url_serde")]
#[cfg_attr(feature = "with_serde", serde(with = "url_serde"))]
pub face: Url,
}

View File

@ -1,18 +1,18 @@
use crate::models::GrandCompany;
use chrono::{DateTime, Utc};
use ffxiv_types::World;
#[cfg(feature = "with_serde")] use serde_derive::{Deserialize, Serialize};
use url::Url;
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug)]
#[cfg_attr(feature = "with_serde", derive(Deserialize, Serialize))]
pub struct FreeCompanySearchItem {
#[serde(with = "crate::util::serde::u64_str")]
#[cfg_attr(feature = "with_serde", serde(with = "crate::util::serde::u64_str"))]
pub id: u64,
pub name: String,
pub world: World,
#[serde(with = "crate::util::serde::multi_url")]
#[cfg_attr(feature = "with_serde", serde(with = "crate::util::serde::multi_url"))]
pub crest: Vec<Url>,
pub grand_company: GrandCompany,
pub active_members: u16,

View File

@ -1,8 +1,10 @@
use ffxiv_types::World;
#[cfg(feature = "with_serde")] use serde_derive::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug)]
#[cfg_attr(feature = "with_serde", derive(Deserialize, Serialize))]
pub struct LinkshellSearchItem {
#[serde(with = "crate::util::serde::u64_str")]
#[cfg_attr(feature = "with_serde", serde(with = "crate::util::serde::u64_str"))]
pub id: u64,
pub name: String,
pub world: World,

View File

@ -1 +1 @@
pub mod serde;
#[cfg(feature = "with_serde")] pub mod serde;

View File

@ -2,6 +2,7 @@ use serde::{Deserializer, Deserialize, Serializer, ser::SerializeSeq};
use url::Url;
#[allow(clippy::ptr_arg)]
crate fn serialize<S>(urls: &Vec<Url>, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,
{
@ -16,5 +17,5 @@ crate fn deserialize<'de, D>(deserializer: D) -> Result<Vec<Url>, D::Error>
where D: Deserializer<'de>
{
let urls: Vec<url_serde::De<Url>> = Vec::deserialize(deserializer)?;
Ok(urls.into_iter().map(|u| u.into_inner()).collect())
Ok(urls.into_iter().map(url_serde::De::into_inner).collect())
}

View File

@ -1,5 +1,6 @@
use serde::{Deserializer, Deserialize, Serializer, de::Unexpected};
#[allow(clippy::trivially_copy_pass_by_ref)]
crate fn serialize<S>(u: &u64, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,
{