Skip to content

Commit 50e891a

Browse files
Datetime, string, duration, etc
1 parent 1dc92c6 commit 50e891a

47 files changed

Lines changed: 1845 additions & 1 deletion

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

libsol/cs_display_renderer.c

Lines changed: 394 additions & 0 deletions
Large diffs are not rendered by default.

libsol/cs_display_renderer_test.c

Lines changed: 434 additions & 1 deletion
Large diffs are not rendered by default.

libsol/cs_instruction_template.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,69 @@ int cs_instruction_template_set_format_token_amount(const cs_format_token_amount
203203
return 0;
204204
}
205205

206+
int cs_instruction_template_set_format_datetime(uint32_t ticks_per_second) {
207+
cs_instruction_template_t *builder = cs_instruction_template_current();
208+
if (builder == NULL || builder->display_field_count == 0) {
209+
PRINTF("cs_instruction_template_set_format_datetime: no field to configure\n");
210+
return -1;
211+
}
212+
cs_display_field_t *field = &builder->display_fields[builder->display_field_count - 1];
213+
if (field->source != CS_VALUE_SOURCE_ARGUMENT_PATH) {
214+
PRINTF("cs_instruction_template_set_format_datetime: source %d != ARGUMENT_PATH\n",
215+
field->source);
216+
return -1;
217+
}
218+
if (field->argument.param_type != CS_PARAM_TYPE_DATETIME) {
219+
PRINTF("cs_instruction_template_set_format_datetime: param_type %d != DATETIME\n",
220+
field->argument.param_type);
221+
return -1;
222+
}
223+
field->argument.format.datetime.ticks_per_second = ticks_per_second;
224+
return 0;
225+
}
226+
227+
int cs_instruction_template_set_format_unit(const cs_format_unit_t *format) {
228+
cs_instruction_template_t *builder = cs_instruction_template_current();
229+
if (builder == NULL || builder->display_field_count == 0) {
230+
PRINTF("cs_instruction_template_set_format_unit: no field to configure\n");
231+
return -1;
232+
}
233+
cs_display_field_t *field = &builder->display_fields[builder->display_field_count - 1];
234+
if (field->source != CS_VALUE_SOURCE_ARGUMENT_PATH) {
235+
PRINTF("cs_instruction_template_set_format_unit: source %d != ARGUMENT_PATH\n",
236+
field->source);
237+
return -1;
238+
}
239+
if (field->argument.param_type != CS_PARAM_TYPE_UNIT) {
240+
PRINTF("cs_instruction_template_set_format_unit: param_type %d != UNIT\n",
241+
field->argument.param_type);
242+
return -1;
243+
}
244+
memcpy(&field->argument.format.unit, format, sizeof(*format));
245+
return 0;
246+
}
247+
248+
int cs_instruction_template_set_format_string(const cs_format_string_t *format) {
249+
cs_instruction_template_t *builder = cs_instruction_template_current();
250+
if (builder == NULL || builder->display_field_count == 0) {
251+
PRINTF("cs_instruction_template_set_format_string: no field to configure\n");
252+
return -1;
253+
}
254+
cs_display_field_t *field = &builder->display_fields[builder->display_field_count - 1];
255+
if (field->source != CS_VALUE_SOURCE_ARGUMENT_PATH) {
256+
PRINTF("cs_instruction_template_set_format_string: source %d != ARGUMENT_PATH\n",
257+
field->source);
258+
return -1;
259+
}
260+
if (field->argument.param_type != CS_PARAM_TYPE_STRING) {
261+
PRINTF("cs_instruction_template_set_format_string: param_type %d != STRING\n",
262+
field->argument.param_type);
263+
return -1;
264+
}
265+
memcpy(&field->argument.format.string, format, sizeof(*format));
266+
return 0;
267+
}
268+
206269
// Record which instruction accounts carry the token account and the mint,
207270
// so the finalize step can resolve the mint pubkey for TOKEN_AMOUNT display.
208271
int cs_instruction_template_set_mint_assoc(uint8_t account_idx, uint8_t mint_idx) {

libsol/cs_instruction_template.h

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,62 @@ typedef struct cs_format_amount_s {
4343
uint8_t decimals;
4444
} cs_format_amount_t;
4545

46+
// Format-specific parameters for PARAM_DATETIME. The resolved integer leaf is
47+
// divided by `ticks_per_second` to obtain Unix epoch seconds before formatting.
48+
typedef struct cs_format_datetime_s {
49+
uint32_t ticks_per_second;
50+
} cs_format_datetime_t;
51+
52+
// Format-specific parameters for PARAM_UNIT. The resolved integer leaf is scaled
53+
// by `decimals` and rendered with `symbol` placed before (`prefix`) or after it.
54+
#define CS_MAX_UNIT_SYMBOL 12
55+
typedef struct cs_format_unit_s {
56+
char symbol[CS_MAX_UNIT_SYMBOL];
57+
uint8_t decimals;
58+
bool prefix;
59+
} cs_format_unit_t;
60+
61+
// Text encoding applied to a PARAM_STRING leaf before display.
62+
enum cs_string_encoding {
63+
CS_STRING_ENCODING_ASCII = 0x00,
64+
CS_STRING_ENCODING_UTF8 = 0x01,
65+
CS_STRING_ENCODING_BASE58 = 0x02,
66+
CS_STRING_ENCODING_BASE64 = 0x03,
67+
CS_STRING_ENCODING_HEX = 0x04,
68+
};
69+
70+
// How a PARAM_STRING slice window is expressed.
71+
enum cs_slice_kind {
72+
CS_SLICE_KIND_BOUNDED = 0x00, // [start, end)
73+
CS_SLICE_KIND_SIZED = 0x01, // `size` units from start, or from the tail when reversed
74+
};
75+
76+
// Whether a PARAM_STRING slice operates on the raw source bytes or on the
77+
// post-encoding formatted string.
78+
enum cs_slice_applies_to {
79+
CS_SLICE_APPLIES_TO_FORMATTED = 0x00,
80+
CS_SLICE_APPLIES_TO_SOURCE = 0x01,
81+
};
82+
83+
// Format-specific parameters for PARAM_STRING. `slice_kind` selects the active
84+
// `slice` arm; `slice_start` is shared by BOUNDED and forward SIZED.
85+
typedef struct cs_format_string_s {
86+
uint8_t encoding; // enum cs_string_encoding
87+
bool has_slice;
88+
uint8_t slice_kind; // enum cs_slice_kind
89+
uint8_t slice_applies_to; // enum cs_slice_applies_to
90+
uint16_t slice_start;
91+
union {
92+
struct {
93+
uint16_t end; // exclusive
94+
} bounded; // CS_SLICE_KIND_BOUNDED
95+
struct {
96+
uint16_t size;
97+
bool reversed; // take the trailing window
98+
} sized; // CS_SLICE_KIND_SIZED
99+
} slice;
100+
} cs_format_string_t;
101+
46102
// Where a TOKEN_AMOUNT's ticker/decimals metadata comes from. Exactly one
47103
// applies, so contradictory combinations (native carrying a mint reference, a
48104
// stale payload behind an absent reference) are unrepresentable. ARGUMENT_PATH
@@ -105,6 +161,9 @@ typedef struct cs_display_field_s {
105161
union {
106162
cs_format_amount_t amount;
107163
cs_format_token_amount_t token_amount;
164+
cs_format_datetime_t datetime;
165+
cs_format_unit_t unit;
166+
cs_format_string_t string;
108167
} format;
109168
} argument;
110169
struct {
@@ -182,6 +241,21 @@ int cs_instruction_template_set_format_amount(uint8_t decimals);
182241
// Returns 0 on success, -1 when no matching field is open.
183242
int cs_instruction_template_set_format_token_amount(const cs_format_token_amount_t *format);
184243

244+
// Set DATETIME format parameters on the last added display field.
245+
// Must be called immediately after adding a field with param_type == DATETIME.
246+
// Returns 0 on success, -1 when no matching field is open.
247+
int cs_instruction_template_set_format_datetime(uint32_t ticks_per_second);
248+
249+
// Set UNIT format parameters on the last added display field.
250+
// Must be called immediately after adding a field with param_type == UNIT.
251+
// Returns 0 on success, -1 when no matching field is open.
252+
int cs_instruction_template_set_format_unit(const cs_format_unit_t *format);
253+
254+
// Set STRING format parameters on the last added display field.
255+
// Must be called immediately after adding a field with param_type == STRING.
256+
// Returns 0 on success, -1 when no matching field is open.
257+
int cs_instruction_template_set_format_string(const cs_format_string_t *format);
258+
185259
// Set mint association indices on the in-flight builder. Both indices refer to
186260
// the instruction's accounts array: `account_idx` is the token account,
187261
// `mint_idx` is the mint account whose pubkey identifies the token.

0 commit comments

Comments
 (0)