Repository navigation
Firebolt CPP 2.0 Model
The Firebolt Model layer defines the generated data model used by Firebolt requests, responses, events, primitive values, enums, and object types.
All generated Firebolt models inherit from a common CRTP-based model contract.
The Model layer is responsible for defining what data looks like while remaining completely independent of transport, runtime connectivity, and request processing concerns.
- Strongly typed generated models
- Shared serialization and deserialization behavior
- Minimal generated code
- Compile-time validation
- No runtime virtual interface overhead
- Transport-independent data contracts
CRTP (Curiously Recurring Template Pattern) is a natural fit because all Firebolt models are generated from specifications and their concrete types are known at compile time.
Unlike transport implementations, which must support runtime substitution, generated Firebolt request, response, and event objects do not require runtime polymorphism.
This allows the framework to:
- Reuse serialization logic across all generated models
- Eliminate virtual method overhead
- Improve type safety
- Reduce generated code duplication
- Simplify model generation
Firebolt models are organized into three primary categories:
FireboltModel<T>
│
┌──────────────────────────────────┼──────────────────────────────────┐
│ │ │
▼ ▼ ▼
+----------------------+ +----------------------+ +----------------------+
| FireboltPrimitive<T> | | FireboltEnumModel<T> | | Generated Objects |
+----------------------+ +----------------------+ | FireboltModel<T> |
│ │ +----------------------+
│ │ │
▼ ▼ ▼
FireboltVoid LifecycleState DeviceInfo
FireboltString IfaType Ifa
FireboltBoolean ActionIntentRequest
FireboltInteger
FireboltFloat
UUID
IntentId
The Firebolt Model framework is built upon four foundational types that provide serialization, deserialization, and type-safe model conversion across all generated Firebolt APIs.
FireboltObject serves as the generic runtime representation of Firebolt data.
All generated models ultimately serialize into and deserialize from a FireboltObject instance.
This allows the framework to hide its internal JSON representation while exposing a simple and type-safe API to generated models.
class FireboltObject
{
public:
FireboltObject();
template<typename T>
void set(const std::string& name,
const T& value);
template<typename T>
T get(const std::string& name) const;
std::string toString() const;
void fromString(const std::string& payload);
};
The implementation inside libfirebolt-client.so can be:
struct FireboltObject::Impl { nlohmann::json json; };
Responsibilities:
- Dynamic object storage
- String serialization
- String deserialization
- Model interoperability
- Internal JSON abstraction
FireboltModel<T> is the core CRTP contract used by all generated Firebolt models.
It provides shared serialization and deserialization behavior while delegating model-specific field mappings back to the generated type.
template<typename T>
class FireboltModel
{
public:
std::string toString() const;
void fromString(const std::string& payload);
FireboltObject toObject() const;
void fromObject(const FireboltObject& object);
};
class Ifa :
public FireboltModel<Ifa>
{
public:
FireboltString ifa;
IfaType ifaType;
FireboltBoolean lmt;
void write(FireboltObject& object) const
{
object["ifa"] = ifa.toObject();
object["ifa_type"] = ifaType.toObject();
object["lmt"] = lmt.toObject();
}
void read(const FireboltObject& object)
{
ifa.fromObject(
object["ifa"]);
ifaType.fromObject(
object["ifa_type"]);
lmt.fromObject(
object["lmt"]);
}
};Responsibilities:
- Model serialization
- Model deserialization
- Object conversion
- String conversion
- Common model infrastructure
FireboltPrimitive<T> provides a lightweight wrapper around primitive C++ types.
Primitive Firebolt types inherit all conversion behavior automatically.
template<typename T>
class FireboltPrimitive :
public FireboltModel<FireboltPrimitive<T>>
{
public:
T value;
void write(FireboltObject& object) const
{
object.set(value);
}
void read(const FireboltObject& object)
{
value = object.get<T>();
}
};
struct NullType
{
};
template<>
class FireboltPrimitive<NullType> :
public FireboltModel<FireboltPrimitive<NullType>>
{
public:
void write(FireboltObject& object) const
{
object.setNull();
}
void read(const FireboltObject&)
{
// no-op
}
};
using FireboltString = FireboltPrimitive<std::string>;
using FireboltBoolean = FireboltPrimitive<bool>;
using FireboltInteger = FireboltPrimitive<int32_t>;
using FireboltUnsignedInteger = FireboltPrimitive<uint32_t>;
using FireboltFloat = FireboltPrimitive<double>;
using FireboltVoid = FireboltPrimitive<NullType>;
Responsibilities:
- Primitive serialization
- Primitive deserialization
- Type safety
- Conversion reuse
FireboltEnumModel<T> provides a reusable framework for generated Firebolt enumerations.
The framework supplies serialization and conversion behavior while generated types provide enum definitions and string mappings.
template<typename T>
class FireboltEnumModel
: public FireboltModel<T>
{
public:
std::string toString() const;
static T fromString(
const std::string& value);
};
class LimitAdTracking :
public FireboltEnumModel<LimitAdTracking>
{
public:
enum Value
{
Disabled,
Enabled
};
Value value;
std::string toStringValue() const
{
return value == Enabled ? "1" : "0";
}
void fromStringValue(
const std::string& str)
{
value =
(str == "1")
? Enabled
: Disabled;
}
};Responsibilities:
- Enum serialization
- Enum deserialization
- Enum/string mapping
- Conversion reuse