Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions http/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ features = ["http1", "native-tokio", "logging", "tls12"]
version = "2.0.5"
path = "../model"

[dev-dependencies]
uuid = "1.21"

[features]
blocking = []
redis = ["dep:redis"]
Expand Down
5 changes: 3 additions & 2 deletions http/src/client/requester.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,11 @@ pub trait Requester<const AUTHENTICATED: bool, const FORCE: bool>: Sized + Sync
}
};

let formated_id = T::format_id(&id);
let request = build_request::<T, String, Self, AUTHENTICATED, FORCE>(
self,
T::format_url(T::format_id(&id).as_ref()),
None,
T::format_url(&formated_id),
T::extra_queries(&formated_id),
)?;

let response = exec_req::<Self, AUTHENTICATED, FORCE>(self, request).await?;
Expand Down
55 changes: 55 additions & 0 deletions http/tests/guild.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#![cfg(feature = "blocking")]

use gw2lib::Requester;
use gw2lib_model::guild::{
emblem::{GuildEmblemBackground, GuildEmblemForeground},
permissions::GuildPermission,
search::GuildSearch,
upgrades::GuildUpgrade,
Guild,
};
use uuid::uuid;

pub mod setup;

#[test]
fn by_id() {
let client = setup::setup();
let gid = uuid!("4BBB52AA-D768-4FC6-8EDE-C299F2822F0F");
let g: Guild = client.single(gid).unwrap();
assert_eq!(g.id, gid);
}

#[test]
fn emblem_backgrounds() {
let client = setup::setup();
let _: Vec<GuildEmblemBackground> = client.all().unwrap();
}

#[test]
fn emblem_foregrounds() {
let client = setup::setup();
let _: Vec<GuildEmblemForeground> = client.all().unwrap();
}

#[test]
fn permissions() {
let client = setup::setup();
let _: Vec<GuildPermission> = client.all().unwrap();
}

#[test]
fn search() {
let client = setup::setup();
let ids: GuildSearch = client.single("Arenanet".to_owned()).unwrap();
assert_eq!(
ids.0.first().unwrap(),
&uuid!("4BBB52AA-D768-4FC6-8EDE-C299F2822F0F")
)
}

#[test]
fn upgrades() {
let client = setup::setup();
let _: Vec<GuildUpgrade> = client.all().unwrap();
}
4 changes: 4 additions & 0 deletions model/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ path = "src/lib.rs"
[dependencies]
urlencoding = "2.1.2"

[dependencies.uuid]
version = "1.21"
features = ["serde"]

[dependencies.either]
version = "1.8.1"
features = ["serde"]
Expand Down
12 changes: 6 additions & 6 deletions model/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ You don't even need to fork this library to test your struct!

Example commit adding an endpoint: [bcb0bd3](https://github.com/greaka/gw2lib/commit/bcb0bd3e99f135f54fb01d088714ce8471a56d86)

> Last update: 2025/11/03
> Last update: 2026/02/17

- achievements
- [x] achievements
Expand Down Expand Up @@ -107,11 +107,11 @@ Example commit adding an endpoint: [bcb0bd3](https://github.com/greaka/gw2lib/co
- [ ] legends
- guild
- guild
- [ ] :id
- [ ] permissions
- [ ] search
- [ ] upgrades
- [ ] emblem
- [x] :id
- [x] permissions
- [x] search
- [x] upgrades
- [x] emblem
- guild authenticated
- guild
- :id
Expand Down
66 changes: 66 additions & 0 deletions model/src/guild.rs
Original file line number Diff line number Diff line change
@@ -1 +1,67 @@
use serde::{Deserialize, Serialize};
use uuid::Uuid;

use crate::{
guild::emblem::{GuildEmblemBackgroundId, GuildEmblemForegroundId},
misc::colors::ColorId,
Endpoint, EndpointWithId,
};

pub mod emblem;
pub mod permissions;
pub mod search;
pub mod upgrades;

pub type GuildId = Uuid;

#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum GuildEmblemFlag {
FlipBackgroundHorizontal,
FlipBackgroundVertical,
FlipForegroundHorizontal,
FlipForegroundVertical,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct GuildEmblemBackLayer {
pub id: GuildEmblemBackgroundId,
pub colors: Vec<ColorId>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct GuildEmblemForeLayer {
pub id: GuildEmblemForegroundId,
pub colors: Vec<ColorId>,
}



#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct GuildEmblem {
pub background: GuildEmblemBackLayer,
pub foreground: GuildEmblemForeLayer,
pub flags: Vec<GuildEmblemFlag>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct Guild {
pub id: GuildId,
pub name: String,
pub tag: String,
pub emblem: Option<GuildEmblem>,
}

impl Endpoint for Guild {
const AUTHENTICATED: bool = false;
const LOCALE: bool = false;
const URL: &'static str = "v2/guild";
const VERSION: &'static str = "2026-02-17T00:00:00.000Z";
}

impl EndpointWithId for Guild {
type IdType = GuildId;
}
58 changes: 58 additions & 0 deletions model/src/guild/emblem.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use serde::{Deserialize, Serialize};

use crate::{BulkEndpoint, Endpoint, EndpointWithId};

pub type GuildEmblemBackgroundId = u32;
pub type GuildEmblemForegroundId = u32;

#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct GuildEmblemBackground {
pub id: GuildEmblemBackgroundId,
pub layers: Vec<String>,
}

impl Endpoint for GuildEmblemBackground {
const AUTHENTICATED: bool = false;
const LOCALE: bool = false;
const URL: &'static str = "v2/emblem/backgrounds";
const VERSION: &'static str = "2026-02-17T00:00:00.000Z";
}

impl EndpointWithId for GuildEmblemBackground {
type IdType = GuildEmblemBackgroundId;
}

impl BulkEndpoint for GuildEmblemBackground {
const ALL: bool = true;

fn id(&self) -> &Self::IdType {
&self.id
}
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct GuildEmblemForeground {
pub id: GuildEmblemForegroundId,
pub layers: Vec<String>,
}

impl Endpoint for GuildEmblemForeground {
const AUTHENTICATED: bool = false;
const LOCALE: bool = false;
const URL: &'static str = "v2/emblem/foregrounds";
const VERSION: &'static str = "2026-02-17T00:00:00.000Z";
}

impl EndpointWithId for GuildEmblemForeground {
type IdType = GuildEmblemForegroundId;
}

impl BulkEndpoint for GuildEmblemForeground {
const ALL: bool = true;

fn id(&self) -> &Self::IdType {
&self.id
}
}
32 changes: 32 additions & 0 deletions model/src/guild/permissions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use serde::{Deserialize, Serialize};

use crate::{BulkEndpoint, Endpoint, EndpointWithId};

pub type GuildPermissionId = String;

#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct GuildPermission {
pub id: GuildPermissionId,
pub name: String,
pub description: String,
}

impl Endpoint for GuildPermission {
const AUTHENTICATED: bool = false;
const LOCALE: bool = true;
const URL: &'static str = "v2/guild/permissions";
const VERSION: &'static str = "2026-02-17T00:00:00.000Z";
}

impl EndpointWithId for GuildPermission {
type IdType = GuildPermissionId;
}

impl BulkEndpoint for GuildPermission {
const ALL: bool = true;

fn id(&self) -> &Self::IdType {
&self.id
}
}
26 changes: 26 additions & 0 deletions model/src/guild/search.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use serde::{Deserialize, Serialize};

use crate::{guild::GuildId, Endpoint, EndpointWithId};

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(transparent)]
pub struct GuildSearch(pub Vec<GuildId>);

impl Endpoint for GuildSearch {
const AUTHENTICATED: bool = false;
const LOCALE: bool = false;
const URL: &'static str = "v2/guild/search";
const VERSION: &'static str = "2026-02-17T00:00:00.000Z";
}

impl EndpointWithId for GuildSearch {
type IdType = String;

fn format_url(_id: &str) -> String {
Self::URL.to_string()
}

fn extra_queries(id: &str) -> Option<String> {
Some(format!("name={}", id))
}
}
75 changes: 75 additions & 0 deletions model/src/guild/upgrades.rs
Original file line number Diff line number Diff line change
@@ -1 +1,76 @@
use serde::{Deserialize, Serialize};

use crate::{items::ItemId, BulkEndpoint, Endpoint, EndpointWithId};

pub type GuildUpgradeId = u64;

#[derive(Debug, Clone, Deserialize, Serialize)]
pub enum GuildUpgradeType {
AccumulatingCurrency,
BankBag,
Boost,
Claimable,
Consumable,
Decoration,
GuildHall,
GuildHallExpedition,
Hub,
Queue,
Unlock,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub enum GuildUpgradeCostType {
Item,
Collectible,
Currency,
Coins,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct GuildUpgradeCost {
#[serde(rename = "type")]
pub cost_type: GuildUpgradeCostType,
pub name: Option<String>,
pub count: u32,
pub item_id: Option<ItemId>,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct GuildUpgrade {
pub id: GuildUpgradeId,
pub name: String,
pub description: String,
#[serde(rename = "type")]
pub upgrade_type: GuildUpgradeType,
pub icon: String,
pub build_time: u32,
pub required_level: u32,
pub experience: u32,
pub prerequisites: Vec<GuildUpgradeId>,
pub bag_max_items: Option<u32>,
pub bag_max_coins: Option<u32>,
#[serde(default)]
pub cost: Vec<GuildUpgradeCost>,
}

impl Endpoint for GuildUpgrade {
const AUTHENTICATED: bool = false;
const LOCALE: bool = true;
const URL: &'static str = "v2/guild/upgrades";
const VERSION: &'static str = "2026-02-17T00:00:00.000Z";
}

impl EndpointWithId for GuildUpgrade {
type IdType = GuildUpgradeId;
}

impl BulkEndpoint for GuildUpgrade {
const ALL: bool = true;

fn id(&self) -> &Self::IdType {
&self.id
}
}
5 changes: 5 additions & 0 deletions model/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ pub trait EndpointWithId: Endpoint {
fn format_url(id: &str) -> String {
format!("{}/{}", Self::URL, id)
}

#[expect(unused_variables)]
fn extra_queries(id: &str) -> Option<String> {
None
}
}

pub trait FixedEndpoint: Endpoint {}
Expand Down