Add new shop fields to create & update functions
This commit is contained in:
parent
0e833ed273
commit
e80fb6b9d0
12
bindings.h
12
bindings.h
@ -118,6 +118,11 @@ struct RawShop {
|
|||||||
int32_t id;
|
int32_t id;
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *description;
|
const char *description;
|
||||||
|
int32_t gold;
|
||||||
|
const char *shop_type;
|
||||||
|
const char **vendor_keywords;
|
||||||
|
uintptr_t vendor_keywords_len;
|
||||||
|
bool vendor_keywords_exclude;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RawTransaction {
|
struct RawTransaction {
|
||||||
@ -258,6 +263,11 @@ FFIResult<RawShop> update_shop(const char *api_url,
|
|||||||
const char *api_key,
|
const char *api_key,
|
||||||
uint32_t id,
|
uint32_t id,
|
||||||
const char *name,
|
const char *name,
|
||||||
const char *description);
|
const char *description,
|
||||||
|
int32_t gold,
|
||||||
|
const char *shop_type,
|
||||||
|
const char **vendor_keywords,
|
||||||
|
uintptr_t vendor_keywords_len,
|
||||||
|
bool vendor_keywords_exclude);
|
||||||
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
205
src/shop.rs
205
src/shop.rs
@ -1,4 +1,4 @@
|
|||||||
use std::{ffi::CStr, ffi::CString, os::raw::c_char};
|
use std::{ffi::CStr, ffi::CString, os::raw::c_char, slice};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
@ -21,6 +21,10 @@ pub struct Shop {
|
|||||||
pub name: String,
|
pub name: String,
|
||||||
pub owner_id: Option<i32>,
|
pub owner_id: Option<i32>,
|
||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
|
pub gold: Option<i32>,
|
||||||
|
pub shop_type: Option<String>,
|
||||||
|
pub vendor_keywords: Option<Vec<String>>,
|
||||||
|
pub vendor_keywords_exclude: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Shop {
|
impl Shop {
|
||||||
@ -29,6 +33,10 @@ impl Shop {
|
|||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
owner_id: None,
|
owner_id: None,
|
||||||
description: Some(description.to_string()),
|
description: Some(description.to_string()),
|
||||||
|
gold: None,
|
||||||
|
shop_type: None,
|
||||||
|
vendor_keywords: None,
|
||||||
|
vendor_keywords_exclude: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -39,6 +47,10 @@ pub struct SavedShop {
|
|||||||
pub name: String,
|
pub name: String,
|
||||||
pub owner_id: i32,
|
pub owner_id: i32,
|
||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
|
pub gold: i32,
|
||||||
|
pub shop_type: String,
|
||||||
|
pub vendor_keywords: Vec<String>,
|
||||||
|
pub vendor_keywords_exclude: bool,
|
||||||
pub created_at: NaiveDateTime,
|
pub created_at: NaiveDateTime,
|
||||||
pub updated_at: NaiveDateTime,
|
pub updated_at: NaiveDateTime,
|
||||||
}
|
}
|
||||||
@ -49,16 +61,32 @@ pub struct RawShop {
|
|||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub name: *const c_char,
|
pub name: *const c_char,
|
||||||
pub description: *const c_char,
|
pub description: *const c_char,
|
||||||
|
pub gold: i32,
|
||||||
|
pub shop_type: *const c_char,
|
||||||
|
pub vendor_keywords: *mut *const c_char,
|
||||||
|
pub vendor_keywords_len: usize,
|
||||||
|
pub vendor_keywords_exclude: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<SavedShop> for RawShop {
|
impl From<SavedShop> for RawShop {
|
||||||
fn from(shop: SavedShop) -> Self {
|
fn from(shop: SavedShop) -> Self {
|
||||||
|
let (keywords_ptr, keywords_len, _) = shop
|
||||||
|
.vendor_keywords
|
||||||
|
.into_iter()
|
||||||
|
.map(|keyword| CString::new(keyword).unwrap_or_default().into_raw() as *const c_char)
|
||||||
|
.collect::<Vec<*const c_char>>()
|
||||||
|
.into_raw_parts();
|
||||||
Self {
|
Self {
|
||||||
id: shop.id,
|
id: shop.id,
|
||||||
name: CString::new(shop.name).unwrap_or_default().into_raw(),
|
name: CString::new(shop.name).unwrap_or_default().into_raw(),
|
||||||
description: CString::new(shop.description.unwrap_or_else(|| "".to_string()))
|
description: CString::new(shop.description.unwrap_or_else(|| "".to_string()))
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.into_raw(),
|
.into_raw(),
|
||||||
|
gold: shop.gold,
|
||||||
|
shop_type: CString::new(shop.shop_type).unwrap_or_default().into_raw(),
|
||||||
|
vendor_keywords: keywords_ptr,
|
||||||
|
vendor_keywords_len: keywords_len,
|
||||||
|
vendor_keywords_exclude: shop.vendor_keywords_exclude,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,30 +171,65 @@ pub extern "C" fn update_shop(
|
|||||||
id: u32,
|
id: u32,
|
||||||
name: *const c_char,
|
name: *const c_char,
|
||||||
description: *const c_char,
|
description: *const c_char,
|
||||||
|
gold: i32,
|
||||||
|
shop_type: *const c_char,
|
||||||
|
vendor_keywords: *mut *const c_char,
|
||||||
|
vendor_keywords_len: usize,
|
||||||
|
vendor_keywords_exclude: bool,
|
||||||
) -> FFIResult<RawShop> {
|
) -> FFIResult<RawShop> {
|
||||||
info!("update_shop begin");
|
info!("update_shop begin");
|
||||||
let api_url = unsafe { CStr::from_ptr(api_url) }.to_string_lossy();
|
let api_url = unsafe { CStr::from_ptr(api_url) }.to_string_lossy();
|
||||||
let api_key = unsafe { CStr::from_ptr(api_key) }.to_string_lossy();
|
let api_key = unsafe { CStr::from_ptr(api_key) }.to_string_lossy();
|
||||||
let name = unsafe { CStr::from_ptr(name) }.to_string_lossy();
|
let name = unsafe { CStr::from_ptr(name) }
|
||||||
let description = unsafe { CStr::from_ptr(description) }.to_string_lossy();
|
.to_string_lossy()
|
||||||
|
.to_string();
|
||||||
|
let description = unsafe { CStr::from_ptr(description) }
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string();
|
||||||
|
let shop_type = unsafe { CStr::from_ptr(shop_type) }
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string();
|
||||||
|
let keywords = match vendor_keywords.is_null() {
|
||||||
|
true => vec![],
|
||||||
|
false => unsafe { slice::from_raw_parts(vendor_keywords, vendor_keywords_len) }
|
||||||
|
.iter()
|
||||||
|
.map(|&keyword| {
|
||||||
|
unsafe { CStr::from_ptr(keyword) }
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string()
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
};
|
||||||
info!(
|
info!(
|
||||||
"update_shop api_url: {:?}, api_key: {:?}, name: {:?}, description: {:?}",
|
"update_shop api_url: {:?}, api_key: {:?}, name: {:?}, description: {:?}, gold: {:?}, shop_type: {:?}, keywords: {:?}, keywords_exclude: {:?}",
|
||||||
api_url, api_key, name, description
|
api_url, api_key, name, description, gold, shop_type, keywords, vendor_keywords_exclude
|
||||||
);
|
);
|
||||||
|
|
||||||
fn inner(
|
fn inner(
|
||||||
api_url: &str,
|
api_url: &str,
|
||||||
api_key: &str,
|
api_key: &str,
|
||||||
id: u32,
|
id: u32,
|
||||||
name: &str,
|
name: String,
|
||||||
description: &str,
|
description: String,
|
||||||
|
gold: i32,
|
||||||
|
shop_type: String,
|
||||||
|
vendor_keywords: Vec<String>,
|
||||||
|
vendor_keywords_exclude: bool,
|
||||||
) -> Result<SavedShop> {
|
) -> Result<SavedShop> {
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
let url = Url::parse(api_url)?.join(&format!("v1/shops/{}", id))?;
|
let url = Url::parse(api_url)?.join(&format!("v1/shops/{}", id))?;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
let url = Url::parse(&mockito::server_url())?.join(&format!("v1/shops/{}", id))?;
|
let url = Url::parse(&mockito::server_url())?.join(&format!("v1/shops/{}", id))?;
|
||||||
|
|
||||||
let shop = Shop::from_game(name, description);
|
let shop = Shop {
|
||||||
|
name,
|
||||||
|
owner_id: None,
|
||||||
|
description: Some(description),
|
||||||
|
gold: Some(gold),
|
||||||
|
shop_type: Some(shop_type),
|
||||||
|
vendor_keywords: Some(vendor_keywords),
|
||||||
|
vendor_keywords_exclude: Some(vendor_keywords_exclude),
|
||||||
|
};
|
||||||
info!("created shop from game: {:?}", &shop);
|
info!("created shop from game: {:?}", &shop);
|
||||||
let client = reqwest::blocking::Client::new();
|
let client = reqwest::blocking::Client::new();
|
||||||
let resp = client
|
let resp = client
|
||||||
@ -192,7 +255,17 @@ pub extern "C" fn update_shop(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match inner(&api_url, &api_key, id, &name, &description) {
|
match inner(
|
||||||
|
&api_url,
|
||||||
|
&api_key,
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
gold,
|
||||||
|
shop_type,
|
||||||
|
keywords,
|
||||||
|
vendor_keywords_exclude,
|
||||||
|
) {
|
||||||
Ok(shop) => {
|
Ok(shop) => {
|
||||||
info!("update_shop successful");
|
info!("update_shop successful");
|
||||||
FFIResult::Ok(RawShop::from(shop))
|
FFIResult::Ok(RawShop::from(shop))
|
||||||
@ -370,6 +443,10 @@ mod tests {
|
|||||||
owner_id: 1,
|
owner_id: 1,
|
||||||
name: "name".to_string(),
|
name: "name".to_string(),
|
||||||
description: Some("description".to_string()),
|
description: Some("description".to_string()),
|
||||||
|
gold: 100,
|
||||||
|
shop_type: "general_store".to_string(),
|
||||||
|
vendor_keywords: vec!["VendorNoSale".to_string()],
|
||||||
|
vendor_keywords_exclude: true,
|
||||||
created_at: Utc::now().naive_utc(),
|
created_at: Utc::now().naive_utc(),
|
||||||
updated_at: Utc::now().naive_utc(),
|
updated_at: Utc::now().naive_utc(),
|
||||||
};
|
};
|
||||||
@ -396,6 +473,22 @@ mod tests {
|
|||||||
unsafe { CStr::from_ptr(raw_shop.description).to_string_lossy() },
|
unsafe { CStr::from_ptr(raw_shop.description).to_string_lossy() },
|
||||||
"description"
|
"description"
|
||||||
);
|
);
|
||||||
|
assert_eq!(raw_shop.gold, 100);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { CStr::from_ptr(raw_shop.shop_type).to_string_lossy() },
|
||||||
|
"general_store"
|
||||||
|
);
|
||||||
|
assert!(!raw_shop.vendor_keywords.is_null());
|
||||||
|
let keywords_slice = unsafe {
|
||||||
|
slice::from_raw_parts(raw_shop.vendor_keywords, raw_shop.vendor_keywords_len)
|
||||||
|
};
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { CStr::from_ptr(keywords_slice[0]) }
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string(),
|
||||||
|
"VendorNoSale".to_string(),
|
||||||
|
);
|
||||||
|
assert_eq!(raw_shop.vendor_keywords_exclude, true);
|
||||||
}
|
}
|
||||||
FFIResult::Err(error) => panic!("create_shop returned error: {:?}", unsafe {
|
FFIResult::Err(error) => panic!("create_shop returned error: {:?}", unsafe {
|
||||||
CStr::from_ptr(error).to_string_lossy()
|
CStr::from_ptr(error).to_string_lossy()
|
||||||
@ -434,6 +527,10 @@ mod tests {
|
|||||||
owner_id: 1,
|
owner_id: 1,
|
||||||
name: "name".to_string(),
|
name: "name".to_string(),
|
||||||
description: Some("description".to_string()),
|
description: Some("description".to_string()),
|
||||||
|
gold: 100,
|
||||||
|
shop_type: "general_store".to_string(),
|
||||||
|
vendor_keywords: vec!["VendorNoSale".to_string()],
|
||||||
|
vendor_keywords_exclude: true,
|
||||||
created_at: Utc::now().naive_utc(),
|
created_at: Utc::now().naive_utc(),
|
||||||
updated_at: Utc::now().naive_utc(),
|
updated_at: Utc::now().naive_utc(),
|
||||||
};
|
};
|
||||||
@ -447,7 +544,22 @@ mod tests {
|
|||||||
let api_key = CString::new("api-key").unwrap().into_raw();
|
let api_key = CString::new("api-key").unwrap().into_raw();
|
||||||
let name = CString::new("name").unwrap().into_raw();
|
let name = CString::new("name").unwrap().into_raw();
|
||||||
let description = CString::new("description").unwrap().into_raw();
|
let description = CString::new("description").unwrap().into_raw();
|
||||||
let result = update_shop(api_url, api_key, 1, name, description);
|
let shop_type = CString::new("general_store").unwrap().into_raw();
|
||||||
|
let (keywords_ptr, keywords_len, _) =
|
||||||
|
vec![CString::new("VendorNoSale").unwrap().into_raw() as *const c_char]
|
||||||
|
.into_raw_parts();
|
||||||
|
let result = update_shop(
|
||||||
|
api_url,
|
||||||
|
api_key,
|
||||||
|
1,
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
100,
|
||||||
|
shop_type,
|
||||||
|
keywords_ptr,
|
||||||
|
keywords_len,
|
||||||
|
true,
|
||||||
|
);
|
||||||
mock.assert();
|
mock.assert();
|
||||||
match result {
|
match result {
|
||||||
FFIResult::Ok(raw_shop) => {
|
FFIResult::Ok(raw_shop) => {
|
||||||
@ -460,6 +572,22 @@ mod tests {
|
|||||||
unsafe { CStr::from_ptr(raw_shop.description).to_string_lossy() },
|
unsafe { CStr::from_ptr(raw_shop.description).to_string_lossy() },
|
||||||
"description"
|
"description"
|
||||||
);
|
);
|
||||||
|
assert_eq!(raw_shop.gold, 100);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { CStr::from_ptr(raw_shop.shop_type).to_string_lossy() },
|
||||||
|
"general_store"
|
||||||
|
);
|
||||||
|
assert!(!raw_shop.vendor_keywords.is_null());
|
||||||
|
let keywords_slice = unsafe {
|
||||||
|
slice::from_raw_parts(raw_shop.vendor_keywords, raw_shop.vendor_keywords_len)
|
||||||
|
};
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { CStr::from_ptr(keywords_slice[0]) }
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string(),
|
||||||
|
"VendorNoSale".to_string(),
|
||||||
|
);
|
||||||
|
assert_eq!(raw_shop.vendor_keywords_exclude, true);
|
||||||
}
|
}
|
||||||
FFIResult::Err(error) => panic!("update_shop returned error: {:?}", unsafe {
|
FFIResult::Err(error) => panic!("update_shop returned error: {:?}", unsafe {
|
||||||
CStr::from_ptr(error).to_string_lossy()
|
CStr::from_ptr(error).to_string_lossy()
|
||||||
@ -478,7 +606,22 @@ mod tests {
|
|||||||
let api_key = CString::new("api-key").unwrap().into_raw();
|
let api_key = CString::new("api-key").unwrap().into_raw();
|
||||||
let name = CString::new("name").unwrap().into_raw();
|
let name = CString::new("name").unwrap().into_raw();
|
||||||
let description = CString::new("description").unwrap().into_raw();
|
let description = CString::new("description").unwrap().into_raw();
|
||||||
let result = update_shop(api_url, api_key, 1, name, description);
|
let shop_type = CString::new("general_store").unwrap().into_raw();
|
||||||
|
let (keywords_ptr, keywords_len, _) =
|
||||||
|
vec![CString::new("VendorNoSale").unwrap().into_raw() as *const c_char]
|
||||||
|
.into_raw_parts();
|
||||||
|
let result = update_shop(
|
||||||
|
api_url,
|
||||||
|
api_key,
|
||||||
|
1,
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
100,
|
||||||
|
shop_type,
|
||||||
|
keywords_ptr,
|
||||||
|
keywords_len,
|
||||||
|
true,
|
||||||
|
);
|
||||||
mock.assert();
|
mock.assert();
|
||||||
match result {
|
match result {
|
||||||
FFIResult::Ok(raw_shop) => panic!("update_shop returned Ok result: {:#x?}", raw_shop),
|
FFIResult::Ok(raw_shop) => panic!("update_shop returned Ok result: {:#x?}", raw_shop),
|
||||||
@ -498,6 +641,10 @@ mod tests {
|
|||||||
owner_id: 1,
|
owner_id: 1,
|
||||||
name: "name".to_string(),
|
name: "name".to_string(),
|
||||||
description: Some("description".to_string()),
|
description: Some("description".to_string()),
|
||||||
|
gold: 100,
|
||||||
|
shop_type: "general_store".to_string(),
|
||||||
|
vendor_keywords: vec!["VendorNoSale".to_string()],
|
||||||
|
vendor_keywords_exclude: true,
|
||||||
created_at: Utc::now().naive_utc(),
|
created_at: Utc::now().naive_utc(),
|
||||||
updated_at: Utc::now().naive_utc(),
|
updated_at: Utc::now().naive_utc(),
|
||||||
};
|
};
|
||||||
@ -522,6 +669,22 @@ mod tests {
|
|||||||
unsafe { CStr::from_ptr(raw_shop.description).to_string_lossy() },
|
unsafe { CStr::from_ptr(raw_shop.description).to_string_lossy() },
|
||||||
"description"
|
"description"
|
||||||
);
|
);
|
||||||
|
assert_eq!(raw_shop.gold, 100);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { CStr::from_ptr(raw_shop.shop_type).to_string_lossy() },
|
||||||
|
"general_store"
|
||||||
|
);
|
||||||
|
assert!(!raw_shop.vendor_keywords.is_null());
|
||||||
|
let keywords_slice = unsafe {
|
||||||
|
slice::from_raw_parts(raw_shop.vendor_keywords, raw_shop.vendor_keywords_len)
|
||||||
|
};
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { CStr::from_ptr(keywords_slice[0]) }
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string(),
|
||||||
|
"VendorNoSale".to_string(),
|
||||||
|
);
|
||||||
|
assert_eq!(raw_shop.vendor_keywords_exclude, true);
|
||||||
}
|
}
|
||||||
FFIResult::Err(error) => panic!("get_shop returned error: {:?}", unsafe {
|
FFIResult::Err(error) => panic!("get_shop returned error: {:?}", unsafe {
|
||||||
CStr::from_ptr(error).to_string_lossy()
|
CStr::from_ptr(error).to_string_lossy()
|
||||||
@ -558,6 +721,10 @@ mod tests {
|
|||||||
owner_id: 1,
|
owner_id: 1,
|
||||||
name: "name".to_string(),
|
name: "name".to_string(),
|
||||||
description: Some("description".to_string()),
|
description: Some("description".to_string()),
|
||||||
|
gold: 100,
|
||||||
|
shop_type: "general_store".to_string(),
|
||||||
|
vendor_keywords: vec!["VendorNoSale".to_string()],
|
||||||
|
vendor_keywords_exclude: true,
|
||||||
created_at: Utc::now().naive_utc(),
|
created_at: Utc::now().naive_utc(),
|
||||||
updated_at: Utc::now().naive_utc(),
|
updated_at: Utc::now().naive_utc(),
|
||||||
}];
|
}];
|
||||||
@ -587,6 +754,22 @@ mod tests {
|
|||||||
unsafe { CStr::from_ptr(raw_shop.description).to_string_lossy() },
|
unsafe { CStr::from_ptr(raw_shop.description).to_string_lossy() },
|
||||||
"description"
|
"description"
|
||||||
);
|
);
|
||||||
|
assert_eq!(raw_shop.gold, 100);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { CStr::from_ptr(raw_shop.shop_type).to_string_lossy() },
|
||||||
|
"general_store"
|
||||||
|
);
|
||||||
|
assert!(!raw_shop.vendor_keywords.is_null());
|
||||||
|
let keywords_slice = unsafe {
|
||||||
|
slice::from_raw_parts(raw_shop.vendor_keywords, raw_shop.vendor_keywords_len)
|
||||||
|
};
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { CStr::from_ptr(keywords_slice[0]) }
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string(),
|
||||||
|
"VendorNoSale".to_string(),
|
||||||
|
);
|
||||||
|
assert_eq!(raw_shop.vendor_keywords_exclude, true);
|
||||||
}
|
}
|
||||||
FFIResult::Err(error) => panic!("list_shops returned error: {:?}", unsafe {
|
FFIResult::Err(error) => panic!("list_shops returned error: {:?}", unsafe {
|
||||||
CStr::from_ptr(error).to_string_lossy()
|
CStr::from_ptr(error).to_string_lossy()
|
||||||
|
Loading…
Reference in New Issue
Block a user