Commit 4caf5c6e authored by Miro Knejp's avatar Miro Knejp

"duration" as example of a complex external type

This demonstrates some fancy template usage to provide a std::chrono::duration<rep, period> capable external type. It is mapped to NSTimeInterval and java.time.Duration.

It can be used after importing "duration.yaml" as follows:
- duration<i32, s> => std::chrono::duration<i32, std::ratio<1>>
- duration<f64, ns> => std::chrono::duration<double, std::nano>
parent 55fcd90e
......@@ -11,3 +11,4 @@
@import "primtypes.djinni"
@import "constants.djinni"
@import "date.djinni"
@import "duration.djinni"
@extern "duration.yaml"
test_duration = interface +c {
static hoursString(dt: duration<i32, h>): string;
static minutesString(dt: duration<i32, min>): string;
static secondsString(dt: duration<i32, s>): string;
static millisString(dt: duration<i32, ms>): string;
static microsString(dt: duration<i32, us>): string;
static nanosString(dt: duration<i32, ns>): string;
static hours(count: i32): duration<i32, h>;
static minutes(count: i32): duration<i32, min>;
static seconds(count: i32): duration<i32, s>;
static millis(count: i32): duration<i32, ms>;
static micros(count: i32): duration<i32, us>;
static nanos(count: i32): duration<i32, ns>;
static hoursf(count: f64): duration<f64, h>;
static minutesf(count: f64): duration<f64, min>;
static secondsf(count: f64): duration<f64, s>;
static millisf(count: f64): duration<f64, ms>;
static microsf(count: f64): duration<f64, us>;
static nanosf(count: f64): duration<f64, ns>;
static box(count: i64): optional<duration<i64, s>>;
static unbox(dt: optional<duration<i64, s>>): i64;
}
record_with_duration_and_derivings = record {
dt: duration<f64, ns>;
} deriving(eq, ord)
# This is an example YAML file providing an interface to a chrono::duration based type with customizable representation and period mapped to NSTimeInterval and java.time.Duration.
# Example usage:
# duration<i32, s> maps to std::chrono::duration<int32_t, std::ratio<1>>
# duration<f64, min> maps to std::chrono::duration<double, std::ratio<60>>
---
name: duration
typedef: 'record deriving(eq, ord)'
params: [rep, period]
prefix: ''
cpp:
typename: 'std::chrono::duration'
header: '<chrono>'
byValue: true
objc:
typename: 'NSTimeInterval'
header: '<Foundation/Foundation.h>'
boxed: 'NSNumber'
pointer: false
hash: '(NSUInteger)%s'
objcpp:
translator: '::djinni::Duration'
header: '"Duration-objc.hpp"'
java:
typename: 'java.time.Duration'
boxed: 'java.time.Duration'
reference: true
generic: false
hash: '%s.hashCode()'
jni:
translator: '::djinni::Duration'
header: '"Duration-jni.hpp"'
typename: jobject
typeSignature: 'Ljava/time/Duration;'
---
name: h
typedef: 'record'
params: []
prefix: ''
cpp:
typename: 'std::ratio<3600>'
header: '<chrono>'
byValue: true
objc:
typename: 'NSTimeInterval'
header: '<Foundation/Foundation.h>'
boxed: 'NSNumber'
pointer: false
hash: ''
objcpp:
translator: '::djinni::Duration_h'
header: '"Duration-objc.hpp"'
java:
typename: 'java.time.Duration'
boxed: 'java.time.Duration'
reference: true
generic: false
hash: ''
jni:
translator: '::djinni::Duration_h'
header: '"Duration-jni.hpp"'
typename: jobject
typeSignature: 'Ljava/time/Duration;'
---
name: min
typedef: 'record'
params: []
prefix: ''
cpp:
typename: 'std::ratio<60>'
header: '<chrono>'
byValue: true
objc:
typename: 'NSTimeInterval'
header: '<Foundation/Foundation.h>'
boxed: 'NSNumber'
pointer: false
hash: ''
objcpp:
translator: '::djinni::Duration_min'
header: '"Duration-objc.hpp"'
java:
typename: 'java.time.Duration'
boxed: 'java.time.Duration'
reference: true
generic: false
hash: ''
jni:
translator: '::djinni::Duration_min'
header: '"Duration-jni.hpp"'
typename: jobject
typeSignature: 'Ljava/time/Duration;'
---
name: s
typedef: 'record'
params: []
prefix: ''
cpp:
typename: 'std::ratio<1>'
header: '<chrono>'
byValue: true
objc:
typename: 'NSTimeInterval'
header: '<Foundation/Foundation.h>'
boxed: 'NSNumber'
pointer: false
hash: ''
objcpp:
translator: '::djinni::Duration_s'
header: '"Duration-objc.hpp"'
java:
typename: 'java.time.Duration'
boxed: 'java.time.Duration'
reference: true
generic: false
hash: ''
jni:
translator: '::djinni::Duration_s'
header: '"Duration-jni.hpp"'
typename: jobject
typeSignature: 'Ljava/time/Duration;'
---
name: ms
typedef: 'record'
params: []
prefix: ''
cpp:
typename: 'std::milli'
header: '<chrono>'
byValue: true
objc:
typename: 'NSTimeInterval'
header: '<Foundation/Foundation.h>'
boxed: 'NSNumber'
pointer: false
hash: ''
objcpp:
translator: '::djinni::Duration_ms'
header: '"Duration-objc.hpp"'
java:
typename: 'java.time.Duration'
boxed: 'java.time.Duration'
reference: true
generic: false
hash: ''
jni:
translator: '::djinni::Duration_ms'
header: '"Duration-jni.hpp"'
typename: jobject
typeSignature: 'Ljava/time/Duration;'
---
name: us
typedef: 'record'
params: []
prefix: ''
cpp:
typename: 'std::micro'
header: '<chrono>'
byValue: true
objc:
typename: 'NSTimeInterval'
header: '<Foundation/Foundation.h>'
boxed: 'NSNumber'
pointer: false
hash: ''
objcpp:
translator: '::djinni::Duration_us'
header: '"Duration-objc.hpp"'
java:
typename: 'java.time.Duration'
boxed: 'java.time.Duration'
reference: true
generic: false
hash: ''
jni:
translator: '::djinni::Duration_us'
header: '"Duration-jni.hpp"'
typename: jobject
typeSignature: 'Ljava/time/Duration;'
---
name: ns
typedef: 'record'
params: []
prefix: ''
cpp:
typename: 'std::nano'
header: '<chrono>'
byValue: true
objc:
typename: 'NSTimeInterval'
header: '<Foundation/Foundation.h>'
boxed: 'NSNumber'
pointer: false
hash: ''
objcpp:
translator: '::djinni::Duration_ns'
header: '"Duration-objc.hpp"'
java:
typename: 'java.time.Duration'
boxed: 'java.time.Duration'
reference: true
generic: false
hash: ''
jni:
translator: '::djinni::Duration_ns'
header: '"Duration-jni.hpp"'
typename: jobject
typeSignature: 'Ljava/time/Duration;'
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from duration.djinni
#include "record_with_duration_and_derivings.hpp" // my header
bool operator==(const RecordWithDurationAndDerivings& lhs, const RecordWithDurationAndDerivings& rhs) {
return lhs.dt == rhs.dt;
}
bool operator!=(const RecordWithDurationAndDerivings& lhs, const RecordWithDurationAndDerivings& rhs) {
return !(lhs == rhs);
}
bool operator<(const RecordWithDurationAndDerivings& lhs, const RecordWithDurationAndDerivings& rhs) {
if (lhs.dt < rhs.dt) {
return true;
}
if (rhs.dt < lhs.dt) {
return false;
}
return false;
}
bool operator>(const RecordWithDurationAndDerivings& lhs, const RecordWithDurationAndDerivings& rhs) {
return rhs < lhs;
}
bool operator<=(const RecordWithDurationAndDerivings& lhs, const RecordWithDurationAndDerivings& rhs) {
return !(rhs < lhs);
}
bool operator>=(const RecordWithDurationAndDerivings& lhs, const RecordWithDurationAndDerivings& rhs) {
return !(lhs < rhs);
}
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from duration.djinni
#pragma once
#include <chrono>
#include <utility>
struct RecordWithDurationAndDerivings final {
std::chrono::duration<double, std::nano> dt;
friend bool operator==(const RecordWithDurationAndDerivings& lhs, const RecordWithDurationAndDerivings& rhs);
friend bool operator!=(const RecordWithDurationAndDerivings& lhs, const RecordWithDurationAndDerivings& rhs);
friend bool operator<(const RecordWithDurationAndDerivings& lhs, const RecordWithDurationAndDerivings& rhs);
friend bool operator>(const RecordWithDurationAndDerivings& lhs, const RecordWithDurationAndDerivings& rhs);
friend bool operator<=(const RecordWithDurationAndDerivings& lhs, const RecordWithDurationAndDerivings& rhs);
friend bool operator>=(const RecordWithDurationAndDerivings& lhs, const RecordWithDurationAndDerivings& rhs);
RecordWithDurationAndDerivings(std::chrono::duration<double, std::nano> dt)
: dt(std::move(dt))
{}
};
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from duration.djinni
#pragma once
#include <chrono>
#include <cstdint>
#include <experimental/optional>
#include <string>
class TestDuration {
public:
virtual ~TestDuration() {}
static std::string hoursString(std::chrono::duration<int32_t, std::ratio<3600>> dt);
static std::string minutesString(std::chrono::duration<int32_t, std::ratio<60>> dt);
static std::string secondsString(std::chrono::duration<int32_t, std::ratio<1>> dt);
static std::string millisString(std::chrono::duration<int32_t, std::milli> dt);
static std::string microsString(std::chrono::duration<int32_t, std::micro> dt);
static std::string nanosString(std::chrono::duration<int32_t, std::nano> dt);
static std::chrono::duration<int32_t, std::ratio<3600>> hours(int32_t count);
static std::chrono::duration<int32_t, std::ratio<60>> minutes(int32_t count);
static std::chrono::duration<int32_t, std::ratio<1>> seconds(int32_t count);
static std::chrono::duration<int32_t, std::milli> millis(int32_t count);
static std::chrono::duration<int32_t, std::micro> micros(int32_t count);
static std::chrono::duration<int32_t, std::nano> nanos(int32_t count);
static std::chrono::duration<double, std::ratio<3600>> hoursf(double count);
static std::chrono::duration<double, std::ratio<60>> minutesf(double count);
static std::chrono::duration<double, std::ratio<1>> secondsf(double count);
static std::chrono::duration<double, std::milli> millisf(double count);
static std::chrono::duration<double, std::micro> microsf(double count);
static std::chrono::duration<double, std::nano> nanosf(double count);
static std::experimental::optional<std::chrono::duration<int64_t, std::ratio<1>>> box(int64_t count);
static int64_t unbox(std::experimental::optional<std::chrono::duration<int64_t, std::ratio<1>>> dt);
};
......@@ -13,3 +13,5 @@ djinni/primtypes.djinni
djinni/constants.djinni
djinni/date.djinni
djinni/date.yaml
djinni/duration.djinni
djinni/duration.yaml
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from duration.djinni
package com.dropbox.djinni.test;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
public final class RecordWithDurationAndDerivings implements Comparable<RecordWithDurationAndDerivings> {
/*package*/ final java.time.Duration mDt;
public RecordWithDurationAndDerivings(
@Nonnull java.time.Duration dt) {
this.mDt = dt;
}
@Nonnull
public java.time.Duration getDt() {
return mDt;
}
@Override
public boolean equals(@CheckForNull Object obj) {
if (!(obj instanceof RecordWithDurationAndDerivings)) {
return false;
}
RecordWithDurationAndDerivings other = (RecordWithDurationAndDerivings) obj;
return this.mDt.equals(other.mDt);
}
@Override
public int hashCode() {
// Pick an arbitrary non-zero starting value
int hashCode = 17;
hashCode = hashCode * 31 + (mDt.hashCode());
return hashCode;
}
@Override
public int compareTo(@Nonnull RecordWithDurationAndDerivings other) {
int tempResult;
tempResult = this.mDt.compareTo(other.mDt);
if (tempResult != 0) {
return tempResult;
}
return 0;
}
}
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from duration.djinni
package com.dropbox.djinni.test;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
public abstract class TestDuration {
@Nonnull
public static native String hoursString(@Nonnull java.time.Duration dt);
@Nonnull
public static native String minutesString(@Nonnull java.time.Duration dt);
@Nonnull
public static native String secondsString(@Nonnull java.time.Duration dt);
@Nonnull
public static native String millisString(@Nonnull java.time.Duration dt);
@Nonnull
public static native String microsString(@Nonnull java.time.Duration dt);
@Nonnull
public static native String nanosString(@Nonnull java.time.Duration dt);
@Nonnull
public static native java.time.Duration hours(int count);
@Nonnull
public static native java.time.Duration minutes(int count);
@Nonnull
public static native java.time.Duration seconds(int count);
@Nonnull
public static native java.time.Duration millis(int count);
@Nonnull
public static native java.time.Duration micros(int count);
@Nonnull
public static native java.time.Duration nanos(int count);
@Nonnull
public static native java.time.Duration hoursf(double count);
@Nonnull
public static native java.time.Duration minutesf(double count);
@Nonnull
public static native java.time.Duration secondsf(double count);
@Nonnull
public static native java.time.Duration millisf(double count);
@Nonnull
public static native java.time.Duration microsf(double count);
@Nonnull
public static native java.time.Duration nanosf(double count);
@CheckForNull
public static native java.time.Duration box(long count);
public static native long unbox(@CheckForNull java.time.Duration dt);
public static final class CppProxy extends TestDuration
{
private final long nativeRef;
private final AtomicBoolean destroyed = new AtomicBoolean(false);
private CppProxy(long nativeRef)
{
if (nativeRef == 0) throw new RuntimeException("nativeRef is zero");
this.nativeRef = nativeRef;
}
private native void nativeDestroy(long nativeRef);
public void destroy()
{
boolean destroyed = this.destroyed.getAndSet(true);
if (!destroyed) nativeDestroy(this.nativeRef);
}
protected void finalize() throws java.lang.Throwable
{
destroy();
super.finalize();
}
}
}
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from duration.djinni
#include "NativeRecordWithDurationAndDerivings.hpp" // my header
#include "Duration-jni.hpp"
#include "Marshal.hpp"
namespace djinni_generated {
NativeRecordWithDurationAndDerivings::NativeRecordWithDurationAndDerivings() = default;
NativeRecordWithDurationAndDerivings::~NativeRecordWithDurationAndDerivings() = default;
auto NativeRecordWithDurationAndDerivings::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef<JniType> {
const auto& data = ::djinni::JniClass<NativeRecordWithDurationAndDerivings>::get();
auto r = ::djinni::LocalRef<JniType>{jniEnv->NewObject(data.clazz.get(), data.jconstructor,
::djinni::get(::djinni::Duration<::djinni::F64, ::djinni::Duration_ns>::fromCpp(jniEnv, c.dt)))};
::djinni::jniExceptionCheck(jniEnv);
return r;
}
auto NativeRecordWithDurationAndDerivings::toCpp(JNIEnv* jniEnv, JniType j) -> CppType {
::djinni::JniLocalScope jscope(jniEnv, 2);
assert(j != nullptr);
const auto& data = ::djinni::JniClass<NativeRecordWithDurationAndDerivings>::get();
return {::djinni::Duration<::djinni::F64, ::djinni::Duration_ns>::toCpp(jniEnv, jniEnv->GetObjectField(j, data.field_mDt))};
}
} // namespace djinni_generated
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from duration.djinni
#pragma once
#include "djinni_support.hpp"
#include "record_with_duration_and_derivings.hpp"
namespace djinni_generated {
class NativeRecordWithDurationAndDerivings final {
public:
using CppType = ::RecordWithDurationAndDerivings;
using JniType = jobject;
using Boxed = NativeRecordWithDurationAndDerivings;
~NativeRecordWithDurationAndDerivings();
static CppType toCpp(JNIEnv* jniEnv, JniType j);
static ::djinni::LocalRef<JniType> fromCpp(JNIEnv* jniEnv, const CppType& c);
private:
NativeRecordWithDurationAndDerivings();
friend ::djinni::JniClass<NativeRecordWithDurationAndDerivings>;
const ::djinni::GlobalRef<jclass> clazz { ::djinni::jniFindClass("com/dropbox/djinni/test/RecordWithDurationAndDerivings") };
const jmethodID jconstructor { ::djinni::jniGetMethodID(clazz.get(), "<init>", "(Ljava/time/Duration;)V") };
const jfieldID field_mDt { ::djinni::jniGetFieldID(clazz.get(), "mDt", "Ljava/time/Duration;") };
};
} // namespace djinni_generated
This diff is collapsed.
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from duration.djinni
#pragma once
#include "djinni_support.hpp"
#include "test_duration.hpp"
namespace djinni_generated {
class NativeTestDuration final : ::djinni::JniInterface<::TestDuration, NativeTestDuration> {
public:
using CppType = std::shared_ptr<::TestDuration>;
using JniType = jobject;
using Boxed = NativeTestDuration;
~NativeTestDuration();
static CppType toCpp(JNIEnv* jniEnv, JniType j) { return ::djinni::JniClass<NativeTestDuration>::get()._fromJava(jniEnv, j); }
static ::djinni::LocalRef<JniType> fromCpp(JNIEnv* jniEnv, const CppType& c) { return {jniEnv, ::djinni::JniClass<NativeTestDuration>::get()._toJava(jniEnv, c)}; }
private:
NativeTestDuration();
friend ::djinni::JniClass<NativeTestDuration>;
friend ::djinni::JniInterface<::TestDuration, NativeTestDuration>;
};
} // namespace djinni_generated
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from duration.djinni
#import "DBRecordWithDurationAndDerivings.h"
#include "record_with_duration_and_derivings.hpp"
static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file");
@class DBRecordWithDurationAndDerivings;
namespace djinni_generated {
struct RecordWithDurationAndDerivings
{
using CppType = ::RecordWithDurationAndDerivings;
using ObjcType = DBRecordWithDurationAndDerivings*;
using Boxed = RecordWithDurationAndDerivings;
static CppType toCpp(ObjcType objc);
static ObjcType fromCpp(const CppType& cpp);
};
} // namespace djinni_generated
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from duration.djinni
#import "DBRecordWithDurationAndDerivings+Private.h"
#import "DJIMarshal+Private.h"
#import "Duration-objc.hpp"
#include <cassert>
namespace djinni_generated {
auto RecordWithDurationAndDerivings::toCpp(ObjcType obj) -> CppType
{
assert(obj);
return {::djinni::Duration<::djinni::F64, ::djinni::Duration_ns>::toCpp(obj.dt)};
}
auto RecordWithDurationAndDerivings::fromCpp(const CppType& cpp) -> ObjcType
{
return [[DBRecordWithDurationAndDerivings alloc] initWithDt:(::djinni::Duration<::djinni::F64, ::djinni::Duration_ns>::fromCpp(cpp.dt))];
}
} // namespace djinni_generated
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from duration.djinni
#import <Foundation/Foundation.h>
@interface DBRecordWithDurationAndDerivings : NSObject
- (nonnull id)initWithDt:(NSTimeInterval)dt;
@property (nonatomic, readonly) NSTimeInterval dt;
- (NSComparisonResult)compare:(nonnull DBRecordWithDurationAndDerivings *)other;
@end
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from duration.djinni
#import "DBRecordWithDurationAndDerivings.h"
@implementation DBRecordWithDurationAndDerivings
- (id)initWithDt:(NSTimeInterval)dt
{
if (self = [super init]) {
_dt = dt;
}
return self;
}
- (BOOL)isEqual:(id)other
{
if (![other isKindOfClass:[DBRecordWithDurationAndDerivings class]]) {
return NO;
}
DBRecordWithDurationAndDerivings *typedOther = (DBRecordWithDurationAndDerivings *)other;
return self.dt == typedOther.dt;
}
- (NSUInteger)hash
{
return NSStringFromClass([self class]).hash ^
((NSUInteger)self.dt);
}
- (NSComparisonResult)compare:(DBRecordWithDurationAndDerivings *)other
{
NSComparisonResult tempResult;
if (self.dt < other.dt) {
tempResult = NSOrderedAscending;
} else if (self.dt > other.dt) {
tempResult = NSOrderedDescending;
} else {
tempResult = NSOrderedSame;
}
if (tempResult != NSOrderedSame) {
return tempResult;
}
return NSOrderedSame;
}
@end
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from duration.djinni
#include "test_duration.hpp"
#include <memory>
static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file");
@class DBTestDuration;
namespace djinni_generated {
class TestDuration
{
public:
using CppType = std::shared_ptr<::TestDuration>;
using ObjcType = DBTestDuration*;
using Boxed = TestDuration;
static CppType toCpp(ObjcType objc);
static ObjcType fromCpp(const CppType& cpp);
private:
class ObjcProxy;
};
} // namespace djinni_generated
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from duration.djinni
#import "DBTestDuration+Private.h"
#import "DBTestDuration.h"
#import "DJICppWrapperCache+Private.h"
#import "DJIError.h"
#import "DJIMarshal+Private.h"
#import "Duration-objc.hpp"
#include <exception>
#include <utility>
static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file");
@interface DBTestDuration ()
@property (nonatomic, readonly) ::djinni::DbxCppWrapperCache<::TestDuration>::Handle cppRef;
- (id)initWithCpp:(const std::shared_ptr<::TestDuration>&)cppRef;
@end
@implementation DBTestDuration
- (id)initWithCpp:(const std::shared_ptr<::TestDuration>&)cppRef
{
if (self = [super init]) {
_cppRef.assign(cppRef);
}
return self;
}
+ (nonnull NSString *)hoursString:(NSTimeInterval)dt {
try {
auto r = ::TestDuration::hoursString(::djinni::Duration<::djinni::I32, ::djinni::Duration_h>::toCpp(dt));
return ::djinni::String::fromCpp(r);
} DJINNI_TRANSLATE_EXCEPTIONS()
}
+ (nonnull NSString *)minutesString:(NSTimeInterval)dt {
try {
auto r = ::TestDuration::minutesString(::djinni::Duration<::djinni::I32, ::djinni::Duration_min>::toCpp(dt));
return ::djinni::String::fromCpp(r);
} DJINNI_TRANSLATE_EXCEPTIONS()
}
+ (nonnull NSString *)secondsString:(NSTimeInterval)dt {
try {
auto r = ::TestDuration::secondsString(::djinni::Duration<::djinni::I32, ::djinni::Duration_s>::toCpp(dt));
return ::djinni::String::fromCpp(r);
} DJINNI_TRANSLATE_EXCEPTIONS()
}
+ (nonnull NSString *)millisString:(NSTimeInterval)dt {
try {
auto r = ::TestDuration::millisString(::djinni::Duration<::djinni::I32, ::djinni::Duration_ms>::toCpp(dt));
return ::djinni::String::fromCpp(r);
} DJINNI_TRANSLATE_EXCEPTIONS()
}
+ (nonnull NSString *)microsString:(NSTimeInterval)dt {
try {
auto r = ::TestDuration::microsString(::djinni::Duration<::djinni::I32, ::djinni::Duration_us>::toCpp(dt));
return ::djinni::String::fromCpp(r);
} DJINNI_TRANSLATE_EXCEPTIONS()
}
+ (nonnull NSString *)nanosString:(NSTimeInterval)dt {
try {
auto r = ::TestDuration::nanosString(::djinni::Duration<::djinni::I32, ::djinni::Duration_ns>::toCpp(dt));
return ::djinni::String::fromCpp(r);
} DJINNI_TRANSLATE_EXCEPTIONS()
}
+ (NSTimeInterval)hours:(int32_t)count {
try {
auto r = ::TestDuration::hours(::djinni::I32::toCpp(count));
return ::djinni::Duration<::djinni::I32, ::djinni::Duration_h>::fromCpp(r);
} DJINNI_TRANSLATE_EXCEPTIONS()
}
+ (NSTimeInterval)minutes:(int32_t)count {
try {
auto r = ::TestDuration::minutes(::djinni::I32::toCpp(count));
return ::djinni::Duration<::djinni::I32, ::djinni::Duration_min>::fromCpp(r);
} DJINNI_TRANSLATE_EXCEPTIONS()
}
+ (NSTimeInterval)seconds:(int32_t)count {
try {
auto r = ::TestDuration::seconds(::djinni::I32::toCpp(count));
return ::djinni::Duration<::djinni::I32, ::djinni::Duration_s>::fromCpp(r);
} DJINNI_TRANSLATE_EXCEPTIONS()
}
+ (NSTimeInterval)millis:(int32_t)count {
try {
auto r = ::TestDuration::millis(::djinni::I32::toCpp(count));
return ::djinni::Duration<::djinni::I32, ::djinni::Duration_ms>::fromCpp(r);
} DJINNI_TRANSLATE_EXCEPTIONS()
}
+ (NSTimeInterval)micros:(int32_t)count {
try {
auto r = ::TestDuration::micros(::djinni::I32::toCpp(count));
return ::djinni::Duration<::djinni::I32, ::djinni::Duration_us>::fromCpp(r);
} DJINNI_TRANSLATE_EXCEPTIONS()
}
+ (NSTimeInterval)nanos:(int32_t)count {
try {
auto r = ::TestDuration::nanos(::djinni::I32::toCpp(count));
return ::djinni::Duration<::djinni::I32, ::djinni::Duration_ns>::fromCpp(r);
} DJINNI_TRANSLATE_EXCEPTIONS()
}
+ (NSTimeInterval)hoursf:(double)count {
try {
auto r = ::TestDuration::hoursf(::djinni::F64::toCpp(count));
return ::djinni::Duration<::djinni::F64, ::djinni::Duration_h>::fromCpp(r);
} DJINNI_TRANSLATE_EXCEPTIONS()
}
+ (NSTimeInterval)minutesf:(double)count {
try {
auto r = ::TestDuration::minutesf(::djinni::F64::toCpp(count));
return ::djinni::Duration<::djinni::F64, ::djinni::Duration_min>::fromCpp(r);
} DJINNI_TRANSLATE_EXCEPTIONS()
}
+ (NSTimeInterval)secondsf:(double)count {
try {
auto r = ::TestDuration::secondsf(::djinni::F64::toCpp(count));
return ::djinni::Duration<::djinni::F64, ::djinni::Duration_s>::fromCpp(r);
} DJINNI_TRANSLATE_EXCEPTIONS()
}
+ (NSTimeInterval)millisf:(double)count {
try {
auto r = ::TestDuration::millisf(::djinni::F64::toCpp(count));
return ::djinni::Duration<::djinni::F64, ::djinni::Duration_ms>::fromCpp(r);
} DJINNI_TRANSLATE_EXCEPTIONS()
}
+ (NSTimeInterval)microsf:(double)count {
try {
auto r = ::TestDuration::microsf(::djinni::F64::toCpp(count));
return ::djinni::Duration<::djinni::F64, ::djinni::Duration_us>::fromCpp(r);
} DJINNI_TRANSLATE_EXCEPTIONS()
}
+ (NSTimeInterval)nanosf:(double)count {
try {
auto r = ::TestDuration::nanosf(::djinni::F64::toCpp(count));
return ::djinni::Duration<::djinni::F64, ::djinni::Duration_ns>::fromCpp(r);
} DJINNI_TRANSLATE_EXCEPTIONS()
}
+ (nullable NSNumber *)box:(int64_t)count {
try {
auto r = ::TestDuration::box(::djinni::I64::toCpp(count));
return ::djinni::Optional<std::experimental::optional, ::djinni::Duration<::djinni::I64, ::djinni::Duration_s>>::fromCpp(r);
} DJINNI_TRANSLATE_EXCEPTIONS()
}
+ (int64_t)unbox:(nullable NSNumber *)dt {
try {
auto r = ::TestDuration::unbox(::djinni::Optional<std::experimental::optional, ::djinni::Duration<::djinni::I64, ::djinni::Duration_s>>::toCpp(dt));
return ::djinni::I64::fromCpp(r);
} DJINNI_TRANSLATE_EXCEPTIONS()
}
@end
namespace djinni_generated {
auto TestDuration::toCpp(ObjcType objc) -> CppType
{
if (!objc) {
return nullptr;
}
return objc.cppRef.get();
}
auto TestDuration::fromCpp(const CppType& cpp) -> ObjcType
{
if (!cpp) {
return nil;
}
return ::djinni::DbxCppWrapperCache<::TestDuration>::getInstance()->get(cpp, [] (const CppType& p) {
return [[DBTestDuration alloc] initWithCpp:p];
});
}
} // namespace djinni_generated
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from duration.djinni
#import <Foundation/Foundation.h>
@interface DBTestDuration : NSObject
+ (nonnull NSString *)hoursString:(NSTimeInterval)dt;
+ (nonnull NSString *)minutesString:(NSTimeInterval)dt;
+ (nonnull NSString *)secondsString:(NSTimeInterval)dt;
+ (nonnull NSString *)millisString:(NSTimeInterval)dt;
+ (nonnull NSString *)microsString:(NSTimeInterval)dt;
+ (nonnull NSString *)nanosString:(NSTimeInterval)dt;
+ (NSTimeInterval)hours:(int32_t)count;
+ (NSTimeInterval)minutes:(int32_t)count;
+ (NSTimeInterval)seconds:(int32_t)count;
+ (NSTimeInterval)millis:(int32_t)count;
+ (NSTimeInterval)micros:(int32_t)count;
+ (NSTimeInterval)nanos:(int32_t)count;
+ (NSTimeInterval)hoursf:(double)count;
+ (NSTimeInterval)minutesf:(double)count;
+ (NSTimeInterval)secondsf:(double)count;
+ (NSTimeInterval)millisf:(double)count;
+ (NSTimeInterval)microsf:(double)count;
+ (NSTimeInterval)nanosf:(double)count;
+ (nullable NSNumber *)box:(int64_t)count;
+ (int64_t)unbox:(nullable NSNumber *)dt;
@end
djinni-output-temp/cpp/test_duration.hpp
djinni-output-temp/cpp/record_with_duration_and_derivings.hpp
djinni-output-temp/cpp/record_with_duration_and_derivings.cpp
djinni-output-temp/cpp/date_record.hpp
djinni-output-temp/cpp/date_record.cpp
djinni-output-temp/cpp/map_date_record.hpp
......@@ -22,6 +25,8 @@ djinni-output-temp/cpp/record_with_derivings.cpp
djinni-output-temp/cpp/record_with_nested_derivings.hpp
djinni-output-temp/cpp/record_with_nested_derivings.cpp
djinni-output-temp/cpp/set_record.hpp
djinni-output-temp/java/TestDuration.java
djinni-output-temp/java/RecordWithDurationAndDerivings.java
djinni-output-temp/java/DateRecord.java
djinni-output-temp/java/MapDateRecord.java
djinni-output-temp/java/Constants.java
......@@ -40,6 +45,10 @@ djinni-output-temp/java/NestedCollection.java
djinni-output-temp/java/RecordWithDerivings.java
djinni-output-temp/java/RecordWithNestedDerivings.java
djinni-output-temp/java/SetRecord.java
djinni-output-temp/jni/NativeTestDuration.hpp
djinni-output-temp/jni/NativeTestDuration.cpp
djinni-output-temp/jni/NativeRecordWithDurationAndDerivings.hpp
djinni-output-temp/jni/NativeRecordWithDurationAndDerivings.cpp
djinni-output-temp/jni/NativeDateRecord.hpp
djinni-output-temp/jni/NativeDateRecord.cpp
djinni-output-temp/jni/NativeMapDateRecord.hpp
......@@ -75,6 +84,9 @@ djinni-output-temp/jni/NativeRecordWithNestedDerivings.hpp
djinni-output-temp/jni/NativeRecordWithNestedDerivings.cpp
djinni-output-temp/jni/NativeSetRecord.hpp
djinni-output-temp/jni/NativeSetRecord.cpp
djinni-output-temp/objc/DBTestDuration.h
djinni-output-temp/objc/DBRecordWithDurationAndDerivings.h
djinni-output-temp/objc/DBRecordWithDurationAndDerivings.mm
djinni-output-temp/objc/DBDateRecord.h
djinni-output-temp/objc/DBDateRecord.mm
djinni-output-temp/objc/DBMapDateRecord.h
......@@ -106,6 +118,10 @@ djinni-output-temp/objc/DBRecordWithNestedDerivings.h
djinni-output-temp/objc/DBRecordWithNestedDerivings.mm
djinni-output-temp/objc/DBSetRecord.h
djinni-output-temp/objc/DBSetRecord.mm
djinni-output-temp/objc/DBTestDuration+Private.h
djinni-output-temp/objc/DBTestDuration+Private.mm
djinni-output-temp/objc/DBRecordWithDurationAndDerivings+Private.h
djinni-output-temp/objc/DBRecordWithDurationAndDerivings+Private.mm
djinni-output-temp/objc/DBDateRecord+Private.h
djinni-output-temp/objc/DBDateRecord+Private.mm
djinni-output-temp/objc/DBMapDateRecord+Private.h
......
#pragma once
#include "djinni_support.hpp"
#include <cassert>
#include <chrono>
namespace djinni
{
struct DurationJniInfo
{
const GlobalRef<jclass> clazz { jniFindClass("java/time/Duration") };
const jmethodID method_ofNanos { jniGetStaticMethodID(clazz.get(), "ofNanos", "(J)Ljava/time/Duration;") };
const jmethodID method_toNanos { jniGetMethodID(clazz.get(), "toNanos", "()J") };
};
// This is only a helper, trying to use it as member/param will fail
template<class Ratio>
struct DurationPeriod;
using Duration_h = DurationPeriod<std::ratio<3600>>;
using Duration_min = DurationPeriod<std::ratio<60>>;
using Duration_s = DurationPeriod<std::ratio<1>>;
using Duration_ms = DurationPeriod<std::milli>;
using Duration_us = DurationPeriod<std::micro>;
using Duration_ns = DurationPeriod<std::nano>;
template<class Rep, class Period>
struct Duration;
template<class Rep, class Ratio>
struct Duration<Rep, DurationPeriod<Ratio>>
{
using CppType = std::chrono::duration<typename Rep::CppType, Ratio>;
using JniType = jobject;
using Boxed = Duration;
static CppType toCpp(JNIEnv* jniEnv, JniType j)
{
assert(j != nullptr);
const auto& data = JniClass<DurationJniInfo>::get();
assert(jniEnv->IsInstanceOf(j, data.clazz.get()));
jlong nanos = jniEnv->CallLongMethod(j, data.method_toNanos);
jniExceptionCheck(jniEnv);
return std::chrono::duration_cast<CppType>(std::chrono::duration<jlong, std::nano>{nanos});
}
static LocalRef<jobject> fromCpp(JNIEnv* jniEnv, CppType c)
{
const auto& data = JniClass<DurationJniInfo>::get();
jlong nanos = std::chrono::duration_cast<std::chrono::duration<jlong, std::nano>>(c).count();
auto j = LocalRef<JniType>{jniEnv->CallStaticObjectMethod(data.clazz.get(), data.method_ofNanos, nanos)};
jniExceptionCheck(jniEnv);
return j;
}
};
}
#pragma once
#import <Foundation/Foundation.h>
#include <cassert>
#include <chrono>
namespace djinni
{
// This is only a helper, trying to use it as member/param will fail
template<class Ratio>
struct DurationPeriod;
using Duration_h = DurationPeriod<std::ratio<3600>>;
using Duration_min = DurationPeriod<std::ratio<60>>;
using Duration_s = DurationPeriod<std::ratio<1>>;
using Duration_ms = DurationPeriod<std::milli>;
using Duration_us = DurationPeriod<std::micro>;
using Duration_ns = DurationPeriod<std::nano>;
template<class Rep, class Period>
struct Duration;
template<class Rep, class Ratio>
struct Duration<Rep, DurationPeriod<Ratio>>
{
using CppType = std::chrono::duration<typename Rep::CppType, Ratio>;
using ObjcType = NSTimeInterval;
static CppType toCpp(ObjcType dt)
{
return std::chrono::duration_cast<CppType>(std::chrono::duration<double>{dt});
}
static ObjcType fromCpp(CppType dt)
{
return std::chrono::duration_cast<std::chrono::duration<double>>(dt).count();
}
struct Boxed
{
using ObjcType = NSNumber*;
static CppType toCpp(ObjcType dt)
{
assert(dt);
return std::chrono::duration_cast<CppType>(Duration::toCpp([dt doubleValue]));
}
static ObjcType fromCpp(CppType dt)
{
return [NSNumber numberWithDouble:Duration::fromCpp(dt)];
}
};
};
}
#include "test_duration.hpp"
std::string TestDuration::hoursString(std::chrono::duration<int32_t, std::ratio<3600>> dt)
{
return std::to_string(dt.count());
}
std::string TestDuration::minutesString(std::chrono::duration<int32_t, std::ratio<60>> dt)
{
return std::to_string(dt.count());
}
std::string TestDuration::secondsString(std::chrono::duration<int32_t, std::ratio<1>> dt)
{
return std::to_string(dt.count());
}
std::string TestDuration::millisString(std::chrono::duration<int32_t, std::milli> dt)
{
return std::to_string(dt.count());
}
std::string TestDuration::microsString(std::chrono::duration<int32_t, std::micro> dt)
{
return std::to_string(dt.count());
}
std::string TestDuration::nanosString(std::chrono::duration<int32_t, std::nano> dt)
{
return std::to_string(dt.count());
}
std::chrono::duration<int32_t, std::ratio<3600>> TestDuration::hours(int32_t count)
{
return std::chrono::duration<int32_t, std::ratio<3600>>{count};
}
std::chrono::duration<int32_t, std::ratio<60>> TestDuration::minutes(int32_t count)
{
return std::chrono::duration<int32_t, std::ratio<60>>{count};
}
std::chrono::duration<int32_t, std::ratio<1>> TestDuration::seconds(int32_t count)
{
return std::chrono::duration<int32_t, std::ratio<1>>{count};
}
std::chrono::duration<int32_t, std::milli> TestDuration::millis(int32_t count)
{
return std::chrono::duration<int32_t, std::milli>{count};
}
std::chrono::duration<int32_t, std::micro> TestDuration::micros(int32_t count)
{
return std::chrono::duration<int32_t, std::micro>{count};
}
std::chrono::duration<int32_t, std::nano> TestDuration::nanos(int32_t count)
{
return std::chrono::duration<int32_t, std::nano>{count};
}
std::chrono::duration<double, std::ratio<3600>> TestDuration::hoursf(double count)
{
return std::chrono::duration<double, std::ratio<3600>>{count};
}
std::chrono::duration<double, std::ratio<60>> TestDuration::minutesf(double count)
{
return std::chrono::duration<double, std::ratio<60>>{count};
}
std::chrono::duration<double, std::ratio<1>> TestDuration::secondsf(double count)
{
return std::chrono::duration<double, std::ratio<1>>{count};
}
std::chrono::duration<double, std::milli> TestDuration::millisf(double count)
{
return std::chrono::duration<double, std::milli>{count};
}
std::chrono::duration<double, std::micro> TestDuration::microsf(double count)
{
return std::chrono::duration<double, std::micro>{count};
}
std::chrono::duration<double, std::nano> TestDuration::nanosf(double count)
{
return std::chrono::duration<double, std::nano>{count};
}
std::experimental::optional<std::chrono::duration<int64_t, std::ratio<1>>> TestDuration::box(int64_t count)
{
using D = std::chrono::duration<int64_t, std::ratio<1>>;
using O = std::experimental::optional<D>;
return count < 0 ? O{} : O{D{count}};
}
int64_t TestDuration::unbox(std::experimental::optional<std::chrono::duration<int64_t, std::ratio<1>>> dt)
{
return dt ? dt->count() : -1;
}
......@@ -17,6 +17,7 @@ public class AllTests extends TestSuite {
mySuite.addTestSuite(EnumTest.class);
mySuite.addTestSuite(PrimitivesTest.class);
mySuite.addTestSuite(TokenTest.class);
mySuite.addTestSuite(DurationTest.class);
return mySuite;
}
......
package com.dropbox.djinni.test;
import junit.framework.TestCase;
import java.time.Duration;
public class DurationTest extends TestCase {
public void test() {
assertEquals(TestDuration.hoursString(Duration.ofHours(1)), "1");
assertEquals(TestDuration.minutesString(Duration.ofMinutes(1)), "1");
assertEquals(TestDuration.secondsString(Duration.ofSeconds(1)), "1");
assertEquals(TestDuration.millisString(Duration.ofMillis(1)), "1");
assertEquals(TestDuration.microsString(Duration.ofNanos(1000)), "1");
assertEquals(TestDuration.nanosString(Duration.ofNanos(1)), "1");
assertEquals(TestDuration.hours(1).toHours(), 1);
assertEquals(TestDuration.minutes(1).toMinutes(), 1);
assertEquals(TestDuration.seconds(1).getSeconds(), 1);
assertEquals(TestDuration.millis(1).toMillis(), 1);
assertEquals(TestDuration.micros(1).toNanos(), 1000);
assertEquals(TestDuration.nanos(1).toNanos(), 1);
assertEquals(TestDuration.hoursf(1.5).toMinutes(), 90);
assertEquals(TestDuration.minutesf(1.5).getSeconds(), 90);
assertEquals(TestDuration.secondsf(1.5).toMillis(), 1500);
assertEquals(TestDuration.millisf(1.5).toNanos(), 1500 * 1000);
assertEquals(TestDuration.microsf(1.5).toNanos(), 1500);
assertEquals(TestDuration.nanosf(1.0).toNanos(), 1);
assertEquals(TestDuration.box(1).getSeconds(), 1);
assertEquals(TestDuration.box(-1), null);
assertEquals(TestDuration.unbox(Duration.ofSeconds(1)), 1);
assertEquals(TestDuration.unbox(null), -1);
}
}
#import <Foundation/Foundation.h>
#import "DBTestHelpers.h"
#import "DBTestDuration.h"
#import <XCTest/XCTest.h>
@interface DBDurationTests : XCTestCase
@end
@implementation DBDurationTests
- (void)setUp
{
[super setUp];
}
- (void)tearDown
{
[super tearDown];
}
- (void)test
{
XCTAssertEqual([[DBTestDuration hoursString:3600] compare:@"1"], NSOrderedSame);
XCTAssertEqual([[DBTestDuration minutesString:60] compare:@"1"], NSOrderedSame);
XCTAssertEqual([[DBTestDuration secondsString:1] compare:@"1"], NSOrderedSame);
XCTAssertEqual([[DBTestDuration millisString:0.001] compare:@"1"], NSOrderedSame);
XCTAssertEqual([[DBTestDuration microsString:0.000001] compare:@"1"], NSOrderedSame);
XCTAssertEqual([[DBTestDuration nanosString:0.000000001] compare:@"1"], NSOrderedSame);
XCTAssertEqualWithAccuracy([DBTestDuration hours:1], 3600, 0.001);
XCTAssertEqualWithAccuracy([DBTestDuration minutes:1], 60, 0.001);
XCTAssertEqualWithAccuracy([DBTestDuration seconds:1], 1, 0.001);
XCTAssertEqualWithAccuracy([DBTestDuration millis:1], 0.001, 0.000001);
XCTAssertEqualWithAccuracy([DBTestDuration micros:1], 0.000001, 0.000000001);
XCTAssertEqualWithAccuracy([DBTestDuration nanos:1], 0.000000001, 0.000000000001);
XCTAssertEqualWithAccuracy([DBTestDuration hoursf:1.5], 5400, 0.001);
XCTAssertEqualWithAccuracy([DBTestDuration minutesf:1.5], 90, 0.001);
XCTAssertEqualWithAccuracy([DBTestDuration secondsf:1.5], 1.5, 0.001);
XCTAssertEqualWithAccuracy([DBTestDuration millisf:1.5], 0.0015, 0.000001);
XCTAssertEqualWithAccuracy([DBTestDuration microsf:1.5], 0.0000015, 0.000000001);
XCTAssertEqualWithAccuracy([DBTestDuration nanosf:1.0], 0.000000001, 0.000000000001);
XCTAssertEqual([[DBTestDuration box:1.0] intValue],1);
XCTAssertEqual([DBTestDuration box:-1.0], nil);
XCTAssertEqual([DBTestDuration unbox:[NSNumber numberWithDouble:1.0]], 1);
XCTAssertEqual([DBTestDuration unbox:nil], -1);
}
@end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment