blob: bc4ac0f1f5494efcbc1a52868efc3c511125b5ed [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#ifndef OPENTITAN_SW_DEVICE_LIB_UJSON_UJSON_RUST_H_
#define OPENTITAN_SW_DEVICE_LIB_UJSON_UJSON_RUST_H_
// Definitions of the UJSON macros that emit code that can be trivially
// transformed into rust code:
//
// Preprocess the input, grep out all the preprocessor noise,
// translate `rust_attr` into `#` (rust attributes) and finally format the code:
// gcc -nostdinc -I. -E -DRUST_PREPROCESSOR_EMIT <input_file> \
// | grep -v '#' \
// | sed -e "s/rust_attr/#/g" \
// | rustfmt > output_file
#ifndef RUST_PREPROCESSOR_EMIT
#error "Do not include this file directly. Include ujson_derive.h instead."
#endif // RUST_PREPROCESSOR_EMIT
#include "sw/device/lib/base/adv_macros.h"
#define uint64_t u64
#define uint32_t u32
#define uint16_t u16
#define uint8_t u8
#define size_t usize
#define int64_t i64
#define int32_t i32
#define int16_t i16
#define int8_t i8
#define RUST_DEFAULT_DERIVE \
Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq
// clang-format off
rust_attr[allow(unused_imports)]
use opentitanlib::test_utils::status::status_t;
// clang-format is turned off; as scary as these macros look, they look
// even scarier after clang-format is done with them.
#define ujson_struct_field_array_indirect() ujson_struct_field_array
#define ujson_struct_field_array(t_, sz_, ...) \
OT_IIF(OT_NOT(OT_VA_ARGS_COUNT(dummy, ##__VA_ARGS__))) \
( /*then*/ \
arrayvec::ArrayVec<OT_EXPAND(t_, sz_)> \
, /*else*/ \
arrayvec::ArrayVec<OT_OBSTRUCT(ujson_struct_field_array_indirect)()(t_, __VA_ARGS__), sz_> \
) /*endif*/
#define ujson_struct_field(name_, type_, ...) \
pub OT_IIF(OT_NOT(OT_VA_ARGS_COUNT(dummy, ##__VA_ARGS__))) \
( /*then*/ \
name_: type_ \
, /*else*/ \
name_: OT_EVAL(ujson_struct_field_array(type_, __VA_ARGS__)) \
) /*endif*/,
#define ujson_struct_string(name_, size_, ...) \
ujson_struct_field(name_, String, ##__VA_ARGS__)
#define UJSON_DECLARE_STRUCT(formal_name_, name_, decl_, ...) \
OT_IIF(OT_NOT(OT_VA_ARGS_COUNT(dummy, ##__VA_ARGS__))) \
( /*then*/ \
rust_attr[derive(RUST_DEFAULT_DERIVE)] /*transform into #[...] */ \
, /*else*/ \
rust_attr[derive(__VA_ARGS__)] /*transform into #[...] */ \
) /*endif*/ \
rust_attr[allow(non_camel_case_types)] \
pub struct name_ { \
decl_(ujson_struct_field, ujson_struct_string) \
} \
rust_attr[allow(dead_code)] \
pub type formal_name_ = name_ /*eat_semicolon*/
#define ujson_enum_value(formal_name_, name_, ...) \
pub OT_IIF(OT_NOT(OT_VA_ARGS_COUNT(dummy, ##__VA_ARGS__))) \
( /*then*/ \
name_ \
, /*else*/ \
name_ = __VA_ARGS__ \
) /*endif*/,
#define UJSON_DECLARE_ENUM(formal_name_, name_, decl_, ...) \
OT_IIF(OT_NOT(OT_VA_ARGS_COUNT(dummy, ##__VA_ARGS__))) \
( /*then*/ \
rust_attr[derive(RUST_DEFAULT_DERIVE)] /*transform into #[...] */ \
, /*else*/ \
rust_attr[derive(__VA_ARGS__)] /*transform into #[...] */ \
) /*endif*/ \
rust_attr[repr(u32)] /* transform into #[...] */ \
rust_attr[allow(non_camel_case_types)] \
pub enum name_ { \
decl_(formal_name_, ujson_enum_value) \
RUST_ENUM_INTVALUE (u32), \
} \
rust_attr[allow(dead_code)] \
pub type formal_name_ = name_ /*eat_semicolon*/
// clang-format on
//////////////////////////////////////////////////////////////////////
// Combined build-everything macro
//////////////////////////////////////////////////////////////////////
#define UJSON_SERDE_STRUCT(formal_name_, name_, decl_, ...) \
UJSON_DECLARE_STRUCT(formal_name_, name_, decl_, ##__VA_ARGS__)
#define UJSON_SERDE_ENUM(formal_name_, name_, decl_, ...) \
UJSON_DECLARE_ENUM(formal_name_, name_, decl_, ##__VA_ARGS__)
#define C_ONLY(x) const _ : () = {/* eat a semicolon */}
#define RUST_ONLY(x) x
#endif // OPENTITAN_SW_DEVICE_LIB_UJSON_UJSON_RUST_H_