diff options
Diffstat (limited to 'src/libstore/rust.hh')
-rw-r--r-- | src/libstore/rust.hh | 61 |
1 files changed, 59 insertions, 2 deletions
diff --git a/src/libstore/rust.hh b/src/libstore/rust.hh index 4366e4723..4c7720a44 100644 --- a/src/libstore/rust.hh +++ b/src/libstore/rust.hh @@ -4,7 +4,8 @@ namespace rust { // Depending on the internal representation of Rust slices is slightly // evil... -template<typename T> struct Slice +template<typename T> +struct Slice { T * ptr; size_t size; @@ -37,8 +38,64 @@ struct Source } }; +/* 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); + } +}; + } extern "C" { - void unpack_tarfile(rust::Source source, rust::StringSlice dest_dir); + rust::CBox2<rust::Result<std::tuple<>>> unpack_tarfile(rust::Source source, rust::StringSlice dest_dir); } |