An unofficial collection of APIs used in FreeJam games and mods
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
3.1KB

  1. use reqwest::{Client, Error};
  2. use url::{Url};
  3. use crate::robocraft::{ITokenProvider, DefaultTokenProvider, FactoryInfo, FactorySearchBuilder, RoboShopItemsInfo, FactoryRobotGetInfo};
  4. use crate::robocraft::factory_json::ListPayload;
  5. /// Community Factory Robot root URL
  6. pub const FACTORY_DOMAIN: &str = "https://factory.robocraftgame.com/";
  7. /// CRF API implementation
  8. pub struct FactoryAPI {
  9. client: Client,
  10. token: Box<dyn ITokenProvider>,
  11. }
  12. impl FactoryAPI {
  13. /// Create a new instance, using `DefaultTokenProvider`.
  14. pub fn new() -> FactoryAPI {
  15. FactoryAPI {
  16. client: Client::new(),
  17. token: Box::new(DefaultTokenProvider{}),
  18. }
  19. }
  20. /// Create a new instance using the provided token provider.
  21. pub fn with_auth(token_provider: Box<dyn ITokenProvider>) -> FactoryAPI {
  22. FactoryAPI {
  23. client: Client::new(),
  24. token: token_provider,
  25. }
  26. }
  27. /// Retrieve CRF robots on the main page.
  28. ///
  29. /// For searching, use `list_builder()` instead.
  30. pub async fn list(&self) -> Result<FactoryInfo<RoboShopItemsInfo>, Error> {
  31. let url = Url::parse(FACTORY_DOMAIN)
  32. .unwrap()
  33. .join("/api/roboShopItems/list")
  34. .unwrap();
  35. let payload = ListPayload::default();
  36. let mut request_builder = self.client.post(url)
  37. .json(&payload);
  38. if let Ok(token) = self.token.token() {
  39. request_builder = request_builder.header("Authorization", "Web ".to_owned() + &token);
  40. }
  41. let result = request_builder.send().await;
  42. if let Ok(response) = result {
  43. return response.json::<FactoryInfo<RoboShopItemsInfo>>().await;
  44. }
  45. Err(result.err().unwrap())
  46. }
  47. /// Build a CRF search query.
  48. ///
  49. /// This follows the builder pattern, so functions can be chained.
  50. pub fn list_builder(&self) -> FactorySearchBuilder {
  51. let url = Url::parse(FACTORY_DOMAIN)
  52. .unwrap()
  53. .join("/api/roboShopItems/list")
  54. .unwrap();
  55. let mut token_opt = None;
  56. if let Ok(token) = self.token.token() {
  57. token_opt = Some(token);
  58. }
  59. let request_builder = self.client.post(url);
  60. FactorySearchBuilder::new(request_builder, token_opt)
  61. }
  62. /// Get in-depth info on a CRF robot.
  63. ///
  64. /// `item_id` corresponds to the field with the same name for FactoryRobotGetInfo and FactoryRobotListInfo.
  65. pub async fn get(&self, item_id: usize) -> Result<FactoryInfo<FactoryRobotGetInfo>, Error> {
  66. let url = Url::parse(FACTORY_DOMAIN)
  67. .unwrap()
  68. .join(&format!("/api/roboShopItems/get/{}", item_id))
  69. .unwrap();
  70. let mut request_builder = self.client.get(url);
  71. if let Ok(token) = self.token.token() {
  72. request_builder = request_builder.header("Authorization", "Web ".to_owned() + &token);
  73. }
  74. let result = request_builder.send().await;
  75. if let Ok(response) = result {
  76. return response.json::<FactoryInfo<FactoryRobotGetInfo>>().await;
  77. }
  78. Err(result.err().unwrap())
  79. }
  80. }