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
58 changes: 58 additions & 0 deletions .github/workflows/debian-13-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# test
name: Debian 13 Qt Build

on:
push:
pull_request:

jobs:
build:
runs-on: ubuntu-latest
# This forces the job to run inside a Debian 13 environment
container: debian:trixie

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Install Dependencies
run: |
apt-get update
apt-get install -y \
build-essential \
qt6-base-dev \
qt6-base-private-dev \
libgl1-mesa-dev \
make

- name: Create build directories
run: |
mkdir -p build/example

# Example
- name: Run qmake on example
run: |
cd build/example && qmake6 -makefile ../../example/*.pro

- name: Compile example
run: |
cd build/example && make -j$(nproc)

- name: Run example
run: |
cd build/example
./QSerializeExample

# Benchmarks
# NOTE: Broken build, last change 6 years ago (API break)
#- name: Run qmake on benchmarks
# run: |
# cd build/benchmarks && qmake6 -o ../build/benchmarks/Makefile *.pro

#- name: Compile benchmarks
# run: |
# cd build/benchmarks && make -j$(nproc)

#- name: Run example
# run: |
# cd build/benchmarks && ./benchmarks
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

build
#ignore thumbnails created by windows
Thumbs.db
#Ignore files build by Visual Studio
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
MIT License

Copyright (c) 2020-2021 Agadzhanov Vladimir
Portions Copyright (c) 2021 Jerry Jacobs
Portions Copyright (c) 2021-2026 Jerry Jacobs

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
2 changes: 0 additions & 2 deletions QSerializer

This file was deleted.

59 changes: 42 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,37 @@
[<img alt="logo" width="1280px" src="https://habrastorage.org/webt/t6/e1/vv/t6e1vvxggs9qkz_h5njg4xrzi0k.png" />]()
This project is designed to convert data from an object view to JSON or XML and opposite in the Qt/C++ ecosystem. C ++ classes by default do not have the required meta-object information for serializing class fields, but Qt is equipped with its own highly efficient meta-object system.
An important feature of the QSerializer is the ability to specify serializable fields of the class without having to serialize the entire class. QSerilaizer generate code and declare `Q_PROPERTY` for every declared member of class. This is convenient because you do not need to create separate structures or classes for serialization of write some code to serialize every class, it's just included to QSerializer.

This project is designed to convert data from an object view to JSON or XML and opposite in the Qt/C++ ecosystem. C++ classes by default do not have the required meta-object information for serializing class fields, but Qt is equipped with its own highly efficient meta-object system.

An important feature of the QSerializer is the ability to specify serializable fields of the class without having to serialize the entire class. QSerializer generate code and declare `Q_PROPERTY` for every declared member of class. This is convenient because you do not need to create separate structures or classes for serialization of write some code to serialize every class, it's just included to QSerializer. The serialization code is generated by macros during compilation.

## Installation

Download repository

```bash
$ git clone https://github.com/smurfomen/QSerializer.git
```
Just include qserializer.h in your project and enjoy simple serialization. qserializer.h located in src folder.
Set compiler define `QS_HAS_JSON` or `QS_HAS_XML` for enabling support for xml or json. Enable both at the same time
[is not supported](https://github.com/smurfomen/QSerializer/issues/7).

</br>A demo project for using QSerializer located in example folder.
Just include `QSerializer` in your project and enjoy simple serialization. `qserializer.hpp` located in src folder.
Set compiler define `QS_HAS_JSON` or `QS_HAS_XML` for enabling support for xml or json.



</br>A demo project for using QSerializer located in [`example`](/example) folder.

## Workflow
To get started, include qserializer.h in your code.

To get started:

- `include(QSerializer/src/QSerializer.pri)` from within qmake `.pro` project file
- `#include <QSerializer>` in your C++ code

## Create serialization class

For create serializable member of class and generate propertyes, use macro:

- __QS_FIELD__
- __QS_VALUE__
- __QS_COLLECTION__
- __QS_OBJECT__
- __QS_COLLECTION_OBJECTS__
Expand All @@ -26,23 +40,29 @@ For create serializable member of class and generate propertyes, use macro:
- __QS_STL_DICT__
- __QS_STL_DICT_OBJECTS__

If you want only declare exists fields - use macro QS_JSON_FIELD, QS_XML_FIELD, QS_JSON_COLLECTION and other (look at qserializer.h)
If you want only declare exists fields - use macro `QS_JSON_FIELD`, `QS_XML_FIELD`, `QS_JSON_COLLECTION` and other (look at qserializer.hpp)

### Inherit from QSerializer
Inherit from QSerializer, use macro QS_SERIALIZABLE or override metaObject method and declare some serializable fields.</br>
In this case you must use Q_GADGET in your class.

```C++
class User : public QSerializer
{
Q_GADGET
QS_SERIALIZABLE
// Create data members to be serialized - you can use this members in code
QS_FIELD(int, age)
QS_COLLECTION(QVector, QString, parents)
Q_GADGET
QS_SERIALIZABLE
// Create data members to be serialized - you can use this members in code
QS_FIELD(int, age)
QS_COLLECTION(QVector, QString, parents)
};
```

## **Serialize**

Now you can serialize object of this class to JSON or XML.

For example:

```C++
User u;
u.age = 20;
Expand All @@ -63,11 +83,13 @@ QByteArray dxml = u.toRawXml();
```

## **Deserialize**

Opposite of the serialization procedure is the deserialization procedure.
You can deserialize object from JSON or XML, declared fields will be modified or resets to default for this type values.

For example:

```C++
...
User u;

/* case: json value */
Expand All @@ -86,13 +108,16 @@ u.fromXml(xml);
QByteArray rawXml;
u.fromXml(rawXml);
```

## Macro description

| Macro | Description |
| --------------------- | ------------------------------------------------------------ |
| QSERIALIZABLE | Make class or struct is serializable to QSerializer (override QMetaObject method and define Q_GADGET macro) |
| QS_FIELD | Create serializable simple field |
| QSERIALIZABLE | Make class or struct serializable to `QSerializer` (override QMetaObject method and define Q_GADGET macro) |
| QS_FIELD | Create serializable simple field (based on `QVariant`) |
| QS_VALUE | Create serializable inner custom primitive value type (based on to/from Xml/Json custom methods). Inherit from `QSerializerValue` class |
| QS_COLLECTION | Create serializable collection values of primitive types |
| QS_OBJECT | Create serializable inner custom type object |
| QS_OBJECT | Create serializable inner custom object type |
| QS_COLLECTION_OBJECTS | Create serializable collection of custom type objects |
| QS_QT_DICT | Create serializable dictionary of primitive type values FOR QT DICTIONARY TYPES |
| QS_QT_DICT_OBJECTS | Create serializable dictionary of custom type values FOR QT DICTIONARY TYPES |
Expand Down
2 changes: 1 addition & 1 deletion example/QSerializeExample.pro
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ CONFIG -= app_bundle
DEFINES += QS_HAS_JSON
DEFINES += QS_HAS_XML

include(../qserializer.pri)
include(../src/QSerializer.pri)

SOURCES += \
main.cpp
Expand Down
50 changes: 48 additions & 2 deletions example/classes.h
Original file line number Diff line number Diff line change
@@ -1,21 +1,67 @@
#ifndef CLASSES_H
#define CLASSES_H

#include <QSerializer>
#include <QQueue>
#include <QStack>
#include <QDate>

class CustomDateTime : public QSerializerValue, public QDateTime {
public:
static const Qt::DateFormat fmt = Qt::ISODateWithMs;
using QDateTime::QDateTime;

CustomDateTime& operator=(const QDateTime& other) {
if (this != &other) {
QDateTime::operator=(other);
}

return *this;
}

QJsonValue toJson(void) const {
return QJsonValue(static_cast<const QDateTime&>(*this).toString(Qt::ISODateWithMs));
}

void fromJson(const QJsonValue & varname) {
if (!varname.isString()) {
return;
}
static_cast<QDateTime &>(*this) = QDateTime::fromString(varname.toString(), CustomDateTime::fmt);
}

void fromXml(const QString & val)
{
if (val.isNull()) {
return;
}
static_cast<QDateTime &>(*this) = QDateTime::fromString(val, CustomDateTime::fmt);
}

QString toXml(void) const
{
auto value = static_cast<const QDateTime&>(*this).toString(CustomDateTime::fmt);
return value;
}
};

class Parent : public QSerializer{
Q_GADGET
QS_SERIALIZABLE
public:
Parent(){ }
Parent() {
created_at = QDateTime::currentDateTime();
}
Parent(int age, const QString & name, bool isMale)
: age(age),
name(name),
male(isMale) { }
male(isMale) {
created_at = QDateTime::currentDateTime();
}
QS_FIELD(int, age)
QS_FIELD(QString, name)
QS_FIELD(bool, male)
QS_VALUE(CustomDateTime, created_at)
};

class Student : public QSerializer {
Expand Down
Loading