blob: 3d1a9027b1616a3d19e9c798394c40a8a4dbef4e [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
6namespace cxxbridge = cxxbridge00;
7
8extern "C" {
9const char *cxxbridge00$cxx_string$data(const std::string &s) noexcept {
10 return s.data();
11}
12
13size_t cxxbridge00$cxx_string$length(const std::string &s) noexcept {
14 return s.length();
15}
16
17// RustString
18void cxxbridge00$rust_string$new(cxxbridge::RustString *self) noexcept;
19void cxxbridge00$rust_string$clone(cxxbridge::RustString *self,
20 const cxxbridge::RustString &other) noexcept;
21bool cxxbridge00$rust_string$from(cxxbridge::RustString *self, const char *ptr,
22 size_t len) noexcept;
23void cxxbridge00$rust_string$drop(cxxbridge::RustString *self) noexcept;
24const char *
25cxxbridge00$rust_string$ptr(const cxxbridge::RustString *self) noexcept;
26size_t cxxbridge00$rust_string$len(const cxxbridge::RustString *self) noexcept;
27
28// RustStr
29bool cxxbridge00$rust_str$valid(const char *ptr, size_t len) noexcept;
30} // extern "C"
31
32namespace cxxbridge00 {
33
34RustString::RustString() noexcept { cxxbridge00$rust_string$new(this); }
35
36RustString::RustString(const RustString &other) noexcept {
37 cxxbridge00$rust_string$clone(this, other);
38}
39
40RustString::RustString(RustString &&other) noexcept {
41 this->repr = other.repr;
42 cxxbridge00$rust_string$new(&other);
43}
44
45RustString::RustString(const char *s) {
46 auto len = strlen(s);
47 if (!cxxbridge00$rust_string$from(this, s, len)) {
48 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();
55 if (!cxxbridge00$rust_string$from(this, ptr, len)) {
56 throw std::invalid_argument("data for RustString is not utf-8");
57 }
58}
59
60RustString::~RustString() noexcept { cxxbridge00$rust_string$drop(this); }
61
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) {
68 cxxbridge00$rust_string$drop(this);
69 cxxbridge00$rust_string$clone(this, other);
70 }
71 return *this;
72}
73
74RustString &RustString::operator=(RustString &&other) noexcept {
75 if (this != &other) {
76 cxxbridge00$rust_string$drop(this);
77 this->repr = other.repr;
78 cxxbridge00$rust_string$new(&other);
79 }
80 return *this;
81}
82
83const char *RustString::data() const noexcept {
84 return cxxbridge00$rust_string$ptr(this);
85}
86
87size_t RustString::size() const noexcept {
88 return cxxbridge00$rust_string$len(this);
89}
90
91size_t RustString::length() const noexcept {
92 return cxxbridge00$rust_string$len(this);
93}
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)}) {
104 if (!cxxbridge00$rust_str$valid(this->repr.ptr, this->repr.len)) {
105 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()}) {
110 if (!cxxbridge00$rust_str$valid(this->repr.ptr, this->repr.len)) {
111 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
141} // namespace cxxbridge00
142
143extern "C" {
144void cxxbridge00$unique_ptr$std$string$null(
145 std::unique_ptr<std::string> *ptr) noexcept {
146 new (ptr) std::unique_ptr<std::string>();
147}
148void cxxbridge00$unique_ptr$std$string$new(std::unique_ptr<std::string> *ptr,
149 std::string *value) noexcept {
150 new (ptr) std::unique_ptr<std::string>(new std::string(std::move(*value)));
151}
152void cxxbridge00$unique_ptr$std$string$raw(std::unique_ptr<std::string> *ptr,
153 std::string *raw) noexcept {
154 new (ptr) std::unique_ptr<std::string>(raw);
155}
156const std::string *cxxbridge00$unique_ptr$std$string$get(
157 const std::unique_ptr<std::string> &ptr) noexcept {
158 return ptr.get();
159}
160std::string *cxxbridge00$unique_ptr$std$string$release(
161 std::unique_ptr<std::string> &ptr) noexcept {
162 return ptr.release();
163}
164void cxxbridge00$unique_ptr$std$string$drop(
165 std::unique_ptr<std::string> *ptr) noexcept {
166 ptr->~unique_ptr();
167}
168} // extern "C"