blob: a502d20c9059fcd65f8b9e24da6c9ad738062d30 [file] [log] [blame]
David Tolnay7db73692019-10-20 14:51:12 -04001#include "../include/cxxbridge.h"
2#include <cstring>
3#include <memory>
4#include <stdexcept>
5
David Tolnaye43b7372020-01-08 08:46:20 -08006namespace cxxbridge = cxxbridge01;
David Tolnay7db73692019-10-20 14:51:12 -04007
8extern "C" {
David Tolnaye43b7372020-01-08 08:46:20 -08009const char *cxxbridge01$cxx_string$data(const std::string &s) noexcept {
David Tolnay7db73692019-10-20 14:51:12 -040010 return s.data();
11}
12
David Tolnaye43b7372020-01-08 08:46:20 -080013size_t cxxbridge01$cxx_string$length(const std::string &s) noexcept {
David Tolnay7db73692019-10-20 14:51:12 -040014 return s.length();
15}
16
17// RustString
David Tolnaye43b7372020-01-08 08:46:20 -080018void cxxbridge01$rust_string$new(cxxbridge::RustString *self) noexcept;
19void cxxbridge01$rust_string$clone(cxxbridge::RustString *self,
David Tolnay7db73692019-10-20 14:51:12 -040020 const cxxbridge::RustString &other) noexcept;
David Tolnaye43b7372020-01-08 08:46:20 -080021bool cxxbridge01$rust_string$from(cxxbridge::RustString *self, const char *ptr,
David Tolnay7db73692019-10-20 14:51:12 -040022 size_t len) noexcept;
David Tolnaye43b7372020-01-08 08:46:20 -080023void cxxbridge01$rust_string$drop(cxxbridge::RustString *self) noexcept;
David Tolnay7db73692019-10-20 14:51:12 -040024const char *
David Tolnaye43b7372020-01-08 08:46:20 -080025cxxbridge01$rust_string$ptr(const cxxbridge::RustString *self) noexcept;
26size_t cxxbridge01$rust_string$len(const cxxbridge::RustString *self) noexcept;
David Tolnay7db73692019-10-20 14:51:12 -040027
28// RustStr
David Tolnaye43b7372020-01-08 08:46:20 -080029bool cxxbridge01$rust_str$valid(const char *ptr, size_t len) noexcept;
David Tolnay7db73692019-10-20 14:51:12 -040030} // extern "C"
31
David Tolnaye43b7372020-01-08 08:46:20 -080032namespace cxxbridge01 {
David Tolnay7db73692019-10-20 14:51:12 -040033
David Tolnaye43b7372020-01-08 08:46:20 -080034RustString::RustString() noexcept { cxxbridge01$rust_string$new(this); }
David Tolnay7db73692019-10-20 14:51:12 -040035
36RustString::RustString(const RustString &other) noexcept {
David Tolnaye43b7372020-01-08 08:46:20 -080037 cxxbridge01$rust_string$clone(this, other);
David Tolnay7db73692019-10-20 14:51:12 -040038}
39
40RustString::RustString(RustString &&other) noexcept {
41 this->repr = other.repr;
David Tolnaye43b7372020-01-08 08:46:20 -080042 cxxbridge01$rust_string$new(&other);
David Tolnay7db73692019-10-20 14:51:12 -040043}
44
45RustString::RustString(const char *s) {
46 auto len = strlen(s);
David Tolnaye43b7372020-01-08 08:46:20 -080047 if (!cxxbridge01$rust_string$from(this, s, len)) {
David Tolnay7db73692019-10-20 14:51:12 -040048 throw std::invalid_argument("data for RustString is not utf-8");
49 }
50}
51
52RustString::RustString(const std::string &s) {
53 auto ptr = s.data();
54 auto len = s.length();
David Tolnaye43b7372020-01-08 08:46:20 -080055 if (!cxxbridge01$rust_string$from(this, ptr, len)) {
David Tolnay7db73692019-10-20 14:51:12 -040056 throw std::invalid_argument("data for RustString is not utf-8");
57 }
58}
59
David Tolnaye43b7372020-01-08 08:46:20 -080060RustString::~RustString() noexcept { cxxbridge01$rust_string$drop(this); }
David Tolnay7db73692019-10-20 14:51:12 -040061
62RustString::operator std::string() const {
63 return std::string(this->data(), this->size());
64}
65
66RustString &RustString::operator=(const RustString &other) noexcept {
67 if (this != &other) {
David Tolnaye43b7372020-01-08 08:46:20 -080068 cxxbridge01$rust_string$drop(this);
69 cxxbridge01$rust_string$clone(this, other);
David Tolnay7db73692019-10-20 14:51:12 -040070 }
71 return *this;
72}
73
74RustString &RustString::operator=(RustString &&other) noexcept {
75 if (this != &other) {
David Tolnaye43b7372020-01-08 08:46:20 -080076 cxxbridge01$rust_string$drop(this);
David Tolnay7db73692019-10-20 14:51:12 -040077 this->repr = other.repr;
David Tolnaye43b7372020-01-08 08:46:20 -080078 cxxbridge01$rust_string$new(&other);
David Tolnay7db73692019-10-20 14:51:12 -040079 }
80 return *this;
81}
82
83const char *RustString::data() const noexcept {
David Tolnaye43b7372020-01-08 08:46:20 -080084 return cxxbridge01$rust_string$ptr(this);
David Tolnay7db73692019-10-20 14:51:12 -040085}
86
87size_t RustString::size() const noexcept {
David Tolnaye43b7372020-01-08 08:46:20 -080088 return cxxbridge01$rust_string$len(this);
David Tolnay7db73692019-10-20 14:51:12 -040089}
90
91size_t RustString::length() const noexcept {
David Tolnaye43b7372020-01-08 08:46:20 -080092 return cxxbridge01$rust_string$len(this);
David Tolnay7db73692019-10-20 14:51:12 -040093}
94
95std::ostream &operator<<(std::ostream &os, const RustString &s) {
96 os.write(s.data(), s.size());
97 return os;
98}
99
100RustStr::RustStr() noexcept
101 : repr(Repr{reinterpret_cast<const char *>(this), 0}) {}
102
103RustStr::RustStr(const char *s) : repr(Repr{s, strlen(s)}) {
David Tolnaye43b7372020-01-08 08:46:20 -0800104 if (!cxxbridge01$rust_str$valid(this->repr.ptr, this->repr.len)) {
David Tolnay7db73692019-10-20 14:51:12 -0400105 throw std::invalid_argument("data for RustStr is not utf-8");
106 }
107}
108
109RustStr::RustStr(const std::string &s) : repr(Repr{s.data(), s.length()}) {
David Tolnaye43b7372020-01-08 08:46:20 -0800110 if (!cxxbridge01$rust_str$valid(this->repr.ptr, this->repr.len)) {
David Tolnay7db73692019-10-20 14:51:12 -0400111 throw std::invalid_argument("data for RustStr is not utf-8");
112 }
113}
114
115RustStr::RustStr(const RustStr &) noexcept = default;
116
117RustStr &RustStr::operator=(RustStr other) noexcept {
118 this->repr = other.repr;
119 return *this;
120}
121
122RustStr::operator std::string() const {
123 return std::string(this->data(), this->size());
124}
125
126const char *RustStr::data() const noexcept { return this->repr.ptr; }
127
128size_t RustStr::size() const noexcept { return this->repr.len; }
129
130size_t RustStr::length() const noexcept { return this->repr.len; }
131
132RustStr::RustStr(Repr repr_) noexcept : repr(repr_) {}
133
134RustStr::operator Repr() noexcept { return this->repr; }
135
136std::ostream &operator<<(std::ostream &os, const RustStr &s) {
137 os.write(s.data(), s.size());
138 return os;
139}
140
David Tolnaye43b7372020-01-08 08:46:20 -0800141} // namespace cxxbridge01
David Tolnay7db73692019-10-20 14:51:12 -0400142
143extern "C" {
David Tolnaye43b7372020-01-08 08:46:20 -0800144void cxxbridge01$unique_ptr$std$string$null(
David Tolnay7db73692019-10-20 14:51:12 -0400145 std::unique_ptr<std::string> *ptr) noexcept {
146 new (ptr) std::unique_ptr<std::string>();
147}
David Tolnaye43b7372020-01-08 08:46:20 -0800148void cxxbridge01$unique_ptr$std$string$new(std::unique_ptr<std::string> *ptr,
David Tolnay7db73692019-10-20 14:51:12 -0400149 std::string *value) noexcept {
150 new (ptr) std::unique_ptr<std::string>(new std::string(std::move(*value)));
151}
David Tolnaye43b7372020-01-08 08:46:20 -0800152void cxxbridge01$unique_ptr$std$string$raw(std::unique_ptr<std::string> *ptr,
David Tolnay7db73692019-10-20 14:51:12 -0400153 std::string *raw) noexcept {
154 new (ptr) std::unique_ptr<std::string>(raw);
155}
David Tolnaye43b7372020-01-08 08:46:20 -0800156const std::string *cxxbridge01$unique_ptr$std$string$get(
David Tolnay7db73692019-10-20 14:51:12 -0400157 const std::unique_ptr<std::string> &ptr) noexcept {
158 return ptr.get();
159}
David Tolnaye43b7372020-01-08 08:46:20 -0800160std::string *cxxbridge01$unique_ptr$std$string$release(
David Tolnay7db73692019-10-20 14:51:12 -0400161 std::unique_ptr<std::string> &ptr) noexcept {
162 return ptr.release();
163}
David Tolnaye43b7372020-01-08 08:46:20 -0800164void cxxbridge01$unique_ptr$std$string$drop(
David Tolnay7db73692019-10-20 14:51:12 -0400165 std::unique_ptr<std::string> *ptr) noexcept {
166 ptr->~unique_ptr();
167}
168} // extern "C"