Fix converstion of ByteArray and String

master
Jos van den Oever 2017-08-12 00:18:10 +02:00
parent e468359100
commit e93cb80d26
8 changed files with 135 additions and 51 deletions

View File

@ -85,8 +85,8 @@ enum VariantType {
#[repr(C)] #[repr(C)]
pub struct QVariant<'a> { pub struct QVariant<'a> {
type_: c_uint, type_: VariantType,
len: c_int, value: c_int,
data: *const uint8_t, data: *const uint8_t,
phantom: PhantomData<&'a u8>, phantom: PhantomData<&'a u8>,
} }
@ -96,9 +96,22 @@ impl<'a> QVariant<'a> {
self.type_ as u32 self.type_ as u32
} }
pub fn convert(&self) -> Variant { pub fn convert(&self) -> Variant {
match (self.type_) { match self.type_ {
10 => { VariantType::Bool => {
Variant::String(String::new()) Variant::Bool(self.value != 0)
},
VariantType::String => {
let data = unsafe {
let d = self.data as *const uint16_t;
slice::from_raw_parts(d, self.value as usize)
};
Variant::String(String::from_utf16_lossy(data))
}
VariantType::ByteArray => {
let data = unsafe {
slice::from_raw_parts(self.data, self.value as usize)
};
Variant::ByteArray(Vec::from(data))
} }
_ => Variant::None _ => Variant::None
} }
@ -111,32 +124,32 @@ impl<'a> From<&'a Variant> for QVariant<'a> {
Variant::None => { Variant::None => {
QVariant { QVariant {
data: null(), data: null(),
len: 0, value: 0,
type_: VariantType::Invalid as c_uint, type_: VariantType::Invalid,
phantom: PhantomData, phantom: PhantomData,
} }
} }
Variant::Bool(v) => { Variant::Bool(v) => {
QVariant { QVariant {
data: null(), data: null(),
len: v as c_int, value: v as c_int,
type_: VariantType::Bool as c_uint, type_: VariantType::Bool,
phantom: PhantomData, phantom: PhantomData,
} }
} }
Variant::String(ref v) => { Variant::String(ref v) => {
QVariant { QVariant {
data: v.as_ptr(), data: v.as_ptr(),
len: v.len() as c_int, value: v.len() as c_int,
type_: VariantType::String as c_uint, type_: VariantType::String,
phantom: PhantomData, phantom: PhantomData,
} }
} }
Variant::ByteArray(ref v) => { Variant::ByteArray(ref v) => {
QVariant { QVariant {
data: v.as_ptr(), data: v.as_ptr(),
len: v.len() as c_int, value: v.len() as c_int,
type_: VariantType::ByteArray as c_uint, type_: VariantType::ByteArray,
phantom: PhantomData, phantom: PhantomData,
} }
} }

View File

@ -457,8 +457,9 @@ namespace {
}; };
QVariant variant(const qvariant_t& v) { QVariant variant(const qvariant_t& v) {
switch (v.type) { switch (v.type) {
case QVariant::Bool: return QVariant((bool)v.value);
case QVariant::String: return QString::fromUtf8(static_cast<const char*>(v.data), v.value); case QVariant::String: return QString::fromUtf8(static_cast<const char*>(v.data), v.value);
case QVariant::Bool: return QVariant((bool)v.value);
case QVariant::ByteArray: return QVariant(QByteArray(v.data, v.value));
default:; default:;
} }
return QVariant(); return QVariant();

View File

@ -43,8 +43,9 @@ namespace {
}; };
QVariant variant(const qvariant_t& v) { QVariant variant(const qvariant_t& v) {
switch (v.type) { switch (v.type) {
case QVariant::Bool: return QVariant((bool)v.value);
case QVariant::String: return QString::fromUtf8(static_cast<const char*>(v.data), v.value); case QVariant::String: return QString::fromUtf8(static_cast<const char*>(v.data), v.value);
case QVariant::Bool: return QVariant((bool)v.value);
case QVariant::ByteArray: return QVariant(QByteArray(v.data, v.value));
default:; default:;
} }
return QVariant(); return QVariant();

View File

@ -85,8 +85,8 @@ enum VariantType {
#[repr(C)] #[repr(C)]
pub struct QVariant<'a> { pub struct QVariant<'a> {
type_: c_uint, type_: VariantType,
len: c_int, value: c_int,
data: *const uint8_t, data: *const uint8_t,
phantom: PhantomData<&'a u8>, phantom: PhantomData<&'a u8>,
} }
@ -96,8 +96,25 @@ impl<'a> QVariant<'a> {
self.type_ as u32 self.type_ as u32
} }
pub fn convert(&self) -> Variant { pub fn convert(&self) -> Variant {
// TODO match self.type_ {
Variant::None VariantType::Bool => {
Variant::Bool(self.value != 0)
},
VariantType::String => {
let data = unsafe {
let d = self.data as *const uint16_t;
slice::from_raw_parts(d, self.value as usize)
};
Variant::String(String::from_utf16_lossy(data))
}
VariantType::ByteArray => {
let data = unsafe {
slice::from_raw_parts(self.data, self.value as usize)
};
Variant::ByteArray(Vec::from(data))
}
_ => Variant::None
}
} }
} }
@ -107,32 +124,32 @@ impl<'a> From<&'a Variant> for QVariant<'a> {
Variant::None => { Variant::None => {
QVariant { QVariant {
data: null(), data: null(),
len: 0, value: 0,
type_: VariantType::Invalid as c_uint, type_: VariantType::Invalid,
phantom: PhantomData, phantom: PhantomData,
} }
} }
Variant::Bool(v) => { Variant::Bool(v) => {
QVariant { QVariant {
data: null(), data: null(),
len: v as c_int, value: v as c_int,
type_: VariantType::Bool as c_uint, type_: VariantType::Bool,
phantom: PhantomData, phantom: PhantomData,
} }
} }
Variant::String(ref v) => { Variant::String(ref v) => {
QVariant { QVariant {
data: v.as_ptr(), data: v.as_ptr(),
len: v.len() as c_int, value: v.len() as c_int,
type_: VariantType::String as c_uint, type_: VariantType::String,
phantom: PhantomData, phantom: PhantomData,
} }
} }
Variant::ByteArray(ref v) => { Variant::ByteArray(ref v) => {
QVariant { QVariant {
data: v.as_ptr(), data: v.as_ptr(),
len: v.len() as c_int, value: v.len() as c_int,
type_: VariantType::ByteArray as c_uint, type_: VariantType::ByteArray,
phantom: PhantomData, phantom: PhantomData,
} }
} }

View File

@ -85,8 +85,8 @@ enum VariantType {
#[repr(C)] #[repr(C)]
pub struct QVariant<'a> { pub struct QVariant<'a> {
type_: c_uint, type_: VariantType,
len: c_int, value: c_int,
data: *const uint8_t, data: *const uint8_t,
phantom: PhantomData<&'a u8>, phantom: PhantomData<&'a u8>,
} }
@ -97,13 +97,22 @@ impl<'a> QVariant<'a> {
} }
pub fn convert(&self) -> Variant { pub fn convert(&self) -> Variant {
match self.type_ { match self.type_ {
10 => { VariantType::Bool => {
Variant::Bool(self.value != 0)
},
VariantType::String => {
let data = unsafe { let data = unsafe {
let d = self.data as *const uint16_t; let d = self.data as *const uint16_t;
slice::from_raw_parts(d, self.len as usize) slice::from_raw_parts(d, self.value as usize)
}; };
Variant::String(String::from_utf16_lossy(data)) Variant::String(String::from_utf16_lossy(data))
} }
VariantType::ByteArray => {
let data = unsafe {
slice::from_raw_parts(self.data, self.value as usize)
};
Variant::ByteArray(Vec::from(data))
}
_ => Variant::None _ => Variant::None
} }
} }
@ -115,32 +124,32 @@ impl<'a> From<&'a Variant> for QVariant<'a> {
Variant::None => { Variant::None => {
QVariant { QVariant {
data: null(), data: null(),
len: 0, value: 0,
type_: VariantType::Invalid as c_uint, type_: VariantType::Invalid,
phantom: PhantomData, phantom: PhantomData,
} }
} }
Variant::Bool(v) => { Variant::Bool(v) => {
QVariant { QVariant {
data: null(), data: null(),
len: v as c_int, value: v as c_int,
type_: VariantType::Bool as c_uint, type_: VariantType::Bool,
phantom: PhantomData, phantom: PhantomData,
} }
} }
Variant::String(ref v) => { Variant::String(ref v) => {
QVariant { QVariant {
data: v.as_ptr(), data: v.as_ptr(),
len: v.len() as c_int, value: v.len() as c_int,
type_: VariantType::String as c_uint, type_: VariantType::String,
phantom: PhantomData, phantom: PhantomData,
} }
} }
Variant::ByteArray(ref v) => { Variant::ByteArray(ref v) => {
QVariant { QVariant {
data: v.as_ptr(), data: v.as_ptr(),
len: v.len() as c_int, value: v.len() as c_int,
type_: VariantType::ByteArray as c_uint, type_: VariantType::ByteArray,
phantom: PhantomData, phantom: PhantomData,
} }
} }

View File

@ -43,8 +43,9 @@ namespace {
}; };
QVariant variant(const qvariant_t& v) { QVariant variant(const qvariant_t& v) {
switch (v.type) { switch (v.type) {
case QVariant::Bool: return QVariant((bool)v.value);
case QVariant::String: return QString::fromUtf8(static_cast<const char*>(v.data), v.value); case QVariant::String: return QString::fromUtf8(static_cast<const char*>(v.data), v.value);
case QVariant::Bool: return QVariant((bool)v.value);
case QVariant::ByteArray: return QVariant(QByteArray(v.data, v.value));
default:; default:;
} }
return QVariant(); return QVariant();

View File

@ -1,29 +1,52 @@
#include "test_object_types_rust.h" #include "test_object_types_rust.h"
#include <QTest> #include <QTest>
#include <QSignalSpy> #include <QSignalSpy>
#include <QDebug>
class TestRustObject : public QObject class TestRustObjectTypes : public QObject
{ {
Q_OBJECT Q_OBJECT
private slots: private slots:
void testConstructor(); void testInvalid();
void testStringGetter(); void testBool();
void testStringSetter(); void testString();
void testByteArray();
}; };
void TestRustObject::testConstructor() void TestRustObjectTypes::testInvalid()
{ {
// GIVEN
Person person; Person person;
const QVariant userName;
QSignalSpy spy(&person, &Person::userNameChanged);
// WHEN
person.setUserName(userName);
// THEN
QVERIFY(spy.isValid());
QCOMPARE(spy.count(), 1);
QCOMPARE(person.userName().type(), userName.type());
QCOMPARE(person.userName(), userName);
} }
void TestRustObject::testStringGetter() void TestRustObjectTypes::testBool()
{ {
// GIVEN
Person person; Person person;
person.setUserName("Konqi"); const QVariant userName(true);
QSignalSpy spy(&person, &Person::userNameChanged);
// WHEN
person.setUserName(userName);
// THEN
QVERIFY(spy.isValid());
QCOMPARE(spy.count(), 1);
QCOMPARE(person.userName().type(), userName.type());
QCOMPARE(person.userName(), userName);
} }
void TestRustObject::testStringSetter() void TestRustObjectTypes::testString()
{ {
// GIVEN // GIVEN
Person person; Person person;
@ -40,5 +63,23 @@ void TestRustObject::testStringSetter()
QCOMPARE(person.userName(), userName); QCOMPARE(person.userName(), userName);
} }
QTEST_MAIN(TestRustObject) void TestRustObjectTypes::testByteArray()
{
// GIVEN
Person person;
const char data[10] = {0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9};
const QVariant userName(QByteArray(data, 10));
QSignalSpy spy(&person, &Person::userNameChanged);
// WHEN
person.setUserName(userName);
// THEN
QVERIFY(spy.isValid());
QCOMPARE(spy.count(), 1);
QCOMPARE(person.userName().type(), userName.type());
QCOMPARE(person.userName(), userName);
}
QTEST_MAIN(TestRustObjectTypes)
#include "test_object_types.moc" #include "test_object_types.moc"

View File

@ -43,8 +43,9 @@ namespace {
}; };
QVariant variant(const qvariant_t& v) { QVariant variant(const qvariant_t& v) {
switch (v.type) { switch (v.type) {
case QVariant::Bool: return QVariant((bool)v.value);
case QVariant::String: return QString::fromUtf8(static_cast<const char*>(v.data), v.value); case QVariant::String: return QString::fromUtf8(static_cast<const char*>(v.data), v.value);
case QVariant::Bool: return QVariant((bool)v.value);
case QVariant::ByteArray: return QVariant(QByteArray(v.data, v.value));
default:; default:;
} }
return QVariant(); return QVariant();