diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2019-09-11 12:43:07 +0200 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2019-11-26 22:07:28 +0100 |
commit | b7fba16613aed5c2b2a0b4f98e3e0d32b0cddd40 (patch) | |
tree | 45132643540bafbbe11956a0e547ffe613a37416 /src/libutil/rust-ffi.hh | |
parent | f738cd4d976f4f72159bbcbfa7b451c33f0ea74a (diff) |
Move code around
Diffstat (limited to 'src/libutil/rust-ffi.hh')
-rw-r--r-- | src/libutil/rust-ffi.hh | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/libutil/rust-ffi.hh b/src/libutil/rust-ffi.hh new file mode 100644 index 000000000..a488b96d6 --- /dev/null +++ b/src/libutil/rust-ffi.hh @@ -0,0 +1,97 @@ +#include "serialise.hh" + +namespace rust { + +// Depending on the internal representation of Rust slices is slightly +// evil... +template<typename T> +struct Slice +{ + T * ptr; + size_t size; + + Slice(T * ptr, size_t size) : ptr(ptr), size(size) + { + assert(ptr); + } +}; + +struct StringSlice : Slice<char> +{ + StringSlice(const std::string & s): Slice((char *) s.data(), s.size()) {} +}; + +struct Source +{ + size_t (*fun)(void * source_this, rust::Slice<uint8_t> data); + nix::Source * _this; + + Source(nix::Source & _this) + : fun(sourceWrapper), _this(&_this) + {} + + // FIXME: how to propagate exceptions? + static size_t sourceWrapper(void * _this, rust::Slice<uint8_t> data) + { + auto n = ((nix::Source *) _this)->read(data.ptr, data.size); + return n; + } +}; + +/* C++ representation of Rust's Result<T, CppException>. */ +template<typename T> +struct Result +{ + unsigned int tag; + + union { + T data; + std::exception_ptr * exc; + }; + + /* Rethrow the wrapped exception or return the wrapped value. */ + T unwrap() + { + if (tag == 0) + return data; + else if (tag == 1) + std::rethrow_exception(*exc); + else + abort(); + } +}; + +template<typename T> +struct CBox +{ + T * ptr; + + T * operator ->() + { + return ptr; + } + + CBox(T * ptr) : ptr(ptr) { } + CBox(const CBox &) = delete; + CBox(CBox &&) = delete; + + ~CBox() + { + free(ptr); + } +}; + +// Grrr, this is only needed because 'extern "C"' functions don't +// support non-POD return types (and CBox has a destructor so it's not +// POD). +template<typename T> +struct CBox2 +{ + T * ptr; + CBox<T> use() + { + return CBox(ptr); + } +}; + +} |