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
53 changes: 53 additions & 0 deletions c/csrc/include/longbridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -1312,6 +1312,11 @@ typedef struct lb_oauth_t lb_oauth_t;
*/
typedef struct lb_quote_context_t lb_quote_context_t;

/**
* Statement context
*/
typedef struct CStatementContext CStatementContext;

/**
* Trade context
*/
Expand Down Expand Up @@ -4107,6 +4112,54 @@ typedef struct lb_news_item_t {
extern "C" {
#endif // __cplusplus

/**
* Create a new `StatementContext`
*
* @param config Config object
* @return A new statement context
*/
const struct CStatementContext *lb_statement_context_new(const struct lb_config_t *config);

/**
* Retain the statement context (increment reference count)
*/
void lb_statement_context_retain(const struct CStatementContext *ctx);

/**
* Release the statement context (decrement reference count)
*/
void lb_statement_context_release(const struct CStatementContext *ctx);

/**
* Get statement data list
*
* @param ctx Statement context
* @param statement_type 1 = daily, 2 = monthly
* @param start_date Start date for pagination (0 = default)
* @param limit Number of results (0 = default 20)
* @param callback Async callback
* @param userdata User data passed to the callback
*/
void lb_statement_context_statements(const struct CStatementContext *ctx,
int32_t statement_type,
int32_t start_date,
int32_t limit,
lb_async_callback_t callback,
void *userdata);

/**
* Get statement data download URL
*
* @param ctx Statement context
* @param file_key File key from the list response
* @param callback Async callback
* @param userdata User data passed to the callback
*/
void lb_statement_context_download_url(const struct CStatementContext *ctx,
const char *file_key,
lb_async_callback_t callback,
void *userdata);

/**
* Create a new `Config` using API Key authentication
*
Expand Down
103 changes: 103 additions & 0 deletions c/src/asset_context/context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
use std::{ffi::c_void, os::raw::c_char, sync::Arc};

use longbridge::asset::{GetStatementListOptions, GetStatementOptions, StatementContext, StatementType};

use crate::{
async_call::{CAsyncCallback, execute_async},
config::CConfig,
asset_context::types::CStatementItemOwned,
types::{CString, CVec, cstr_to_rust},
};

/// Statement context
pub struct CStatementContext {
ctx: StatementContext,
}

/// Create a new `StatementContext`
///
/// @param config Config object
/// @return A new statement context
#[unsafe(no_mangle)]
pub unsafe extern "C" fn lb_statement_context_new(
config: *const CConfig,
) -> *const CStatementContext {
let config = Arc::new((*config).0.clone());
let ctx = StatementContext::new(config);
Arc::into_raw(Arc::new(CStatementContext { ctx }))
}

/// Retain the statement context (increment reference count)
#[unsafe(no_mangle)]
pub unsafe extern "C" fn lb_statement_context_retain(ctx: *const CStatementContext) {
Arc::increment_strong_count(ctx);
}

/// Release the statement context (decrement reference count)
#[unsafe(no_mangle)]
pub unsafe extern "C" fn lb_statement_context_release(ctx: *const CStatementContext) {
let _ = Arc::from_raw(ctx);
}

/// Get statement data list
///
/// @param ctx Statement context
/// @param statement_type 1 = daily, 2 = monthly
/// @param start_date Start date for pagination (0 = default)
/// @param limit Number of results (0 = default 20)
/// @param callback Async callback
/// @param userdata User data passed to the callback
#[unsafe(no_mangle)]
pub unsafe extern "C" fn lb_statement_context_statements(
ctx: *const CStatementContext,
statement_type: i32,
start_date: i32,
limit: i32,
callback: CAsyncCallback,
userdata: *mut c_void,
) {
let ctx_inner = (*ctx).ctx.clone();
let st = if statement_type == 2 {
StatementType::Monthly
} else {
StatementType::Daily
};
let mut opts = GetStatementListOptions::new(st);
if start_date > 0 {
opts = opts.page(start_date);
}
if limit > 0 {
opts = opts.page_size(limit);
}
execute_async(callback, ctx, userdata, async move {
let rows: CVec<CStatementItemOwned> =
ctx_inner.statements(opts).await?.list.into();
Ok(rows)
});
}

/// Get statement data download URL
///
/// @param ctx Statement context
/// @param file_key File key from the list response
/// @param callback Async callback
/// @param userdata User data passed to the callback
#[unsafe(no_mangle)]
pub unsafe extern "C" fn lb_statement_context_download_url(
ctx: *const CStatementContext,
file_key: *const c_char,
callback: CAsyncCallback,
userdata: *mut c_void,
) {
let ctx_inner = (*ctx).ctx.clone();
let file_key = cstr_to_rust(file_key);
let opts = GetStatementOptions::new(file_key);
execute_async(callback, ctx, userdata, async move {
let url: CString = ctx_inner
.statement_download_url(opts)
.await?
.url
.into();
Ok(url)
});
}
2 changes: 2 additions & 0 deletions c/src/asset_context/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mod context;
mod types;
39 changes: 39 additions & 0 deletions c/src/asset_context/types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use std::os::raw::c_char;

use longbridge::asset::StatementItem;

use crate::types::{CString, ToFFI};

/// Statement item
#[repr(C)]
pub struct CStatementItem {
/// Statement date (integer, e.g. 20250301)
pub dt: i32,
/// File key
pub file_key: *const c_char,
}

#[derive(Debug)]
pub(crate) struct CStatementItemOwned {
dt: i32,
file_key: CString,
}

impl From<StatementItem> for CStatementItemOwned {
fn from(item: StatementItem) -> Self {
Self {
dt: item.dt,
file_key: item.file_key.into(),
}
}
}

impl ToFFI for CStatementItemOwned {
type FFIType = CStatementItem;
fn to_ffi_type(&self) -> CStatementItem {
CStatementItem {
dt: self.dt,
file_key: self.file_key.to_ffi_type(),
}
}
}
1 change: 1 addition & 0 deletions c/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![allow(unsafe_op_in_unsafe_fn)]

mod asset_context;
mod async_call;
mod callback;
mod config;
Expand Down
61 changes: 61 additions & 0 deletions cpp/include/asset_context.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#pragma once

#include "async_result.hpp"
#include "callback.hpp"
#include "config.hpp"
#include "types.hpp"

typedef struct lb_statement_context_t lb_statement_context_t;

namespace longbridge {
namespace asset {

/// Statement item
struct StatementItem
{
/// Statement date (integer, e.g. 20250301)
int32_t dt;
/// File key
std::string file_key;
};

/// Statement download URL response
struct StatementDownloadUrlResponse
{
/// Presigned download URL
std::string url;
};

/// Statement context
class StatementContext
{
private:
const lb_statement_context_t* ctx_;

public:
StatementContext();
StatementContext(const lb_statement_context_t* ctx);
StatementContext(const StatementContext& ctx);
StatementContext(StatementContext&& ctx);
~StatementContext();

StatementContext& operator=(const StatementContext& ctx);

static StatementContext create(const Config& config);

/// Get statement data list
void statements(
int32_t statement_type,
int32_t start_date,
int32_t limit,
AsyncCallback<StatementContext, std::vector<StatementItem>> callback) const;

/// Get statement data download URL
void statement_download_url(
const std::string& file_key,
AsyncCallback<StatementContext, StatementDownloadUrlResponse> callback)
const;
};

} // namespace asset
} // namespace longbridge
1 change: 1 addition & 0 deletions cpp/include/longbridge.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include "asset_context.hpp"
#include "config.hpp"
#include "decimal.hpp"
#include "http_client.hpp"
Expand Down
Loading