blob: 2952f925378c1a816191bc3288f55d32f1be4e6a [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 Tolnay7db73692019-10-20 14:51:12 -04006extern "C" {
David Tolnaye43b7372020-01-08 08:46:20 -08007const char *cxxbridge01$cxx_string$data(const std::string &s) noexcept {
David Tolnay7db73692019-10-20 14:51:12 -04008 return s.data();
9}
10
David Tolnaye43b7372020-01-08 08:46:20 -080011size_t cxxbridge01$cxx_string$length(const std::string &s) noexcept {
David Tolnay7db73692019-10-20 14:51:12 -040012 return s.length();
13}
14
David Tolnay750755e2020-03-01 13:04:08 -080015// rust::String
16void cxxbridge01$rust_string$new(rust::String *self) noexcept;
17void cxxbridge01$rust_string$clone(rust::String *self,
18 const rust::String &other) noexcept;
19bool cxxbridge01$rust_string$from(rust::String *self, const char *ptr,
David Tolnay7db73692019-10-20 14:51:12 -040020 size_t len) noexcept;
David Tolnay750755e2020-03-01 13:04:08 -080021void cxxbridge01$rust_string$drop(rust::String *self) noexcept;
David Tolnay69fe4c22020-03-01 13:57:24 -080022const char *cxxbridge01$rust_string$ptr(const rust::String *self) noexcept;
David Tolnay750755e2020-03-01 13:04:08 -080023size_t cxxbridge01$rust_string$len(const rust::String *self) noexcept;
David Tolnay7db73692019-10-20 14:51:12 -040024
David Tolnay750755e2020-03-01 13:04:08 -080025// rust::Str
David Tolnaye43b7372020-01-08 08:46:20 -080026bool cxxbridge01$rust_str$valid(const char *ptr, size_t len) noexcept;
David Tolnay7db73692019-10-20 14:51:12 -040027} // extern "C"
28
David Tolnay750755e2020-03-01 13:04:08 -080029namespace rust {
30inline namespace cxxbridge01 {
David Tolnay7db73692019-10-20 14:51:12 -040031
David Tolnay56082162020-03-01 12:57:33 -080032String::String() noexcept { cxxbridge01$rust_string$new(this); }
David Tolnay7db73692019-10-20 14:51:12 -040033
David Tolnay56082162020-03-01 12:57:33 -080034String::String(const String &other) noexcept {
David Tolnaye43b7372020-01-08 08:46:20 -080035 cxxbridge01$rust_string$clone(this, other);
David Tolnay7db73692019-10-20 14:51:12 -040036}
37
David Tolnay56082162020-03-01 12:57:33 -080038String::String(String &&other) noexcept {
David Tolnay7db73692019-10-20 14:51:12 -040039 this->repr = other.repr;
David Tolnaye43b7372020-01-08 08:46:20 -080040 cxxbridge01$rust_string$new(&other);
David Tolnay7db73692019-10-20 14:51:12 -040041}
42
David Tolnay56082162020-03-01 12:57:33 -080043String::String(const char *s) {
David Tolnay7db73692019-10-20 14:51:12 -040044 auto len = strlen(s);
David Tolnaye43b7372020-01-08 08:46:20 -080045 if (!cxxbridge01$rust_string$from(this, s, len)) {
David Tolnay750755e2020-03-01 13:04:08 -080046 throw std::invalid_argument("data for rust::String is not utf-8");
David Tolnay7db73692019-10-20 14:51:12 -040047 }
48}
49
David Tolnay56082162020-03-01 12:57:33 -080050String::String(const std::string &s) {
David Tolnay7db73692019-10-20 14:51:12 -040051 auto ptr = s.data();
52 auto len = s.length();
David Tolnaye43b7372020-01-08 08:46:20 -080053 if (!cxxbridge01$rust_string$from(this, ptr, len)) {
David Tolnay750755e2020-03-01 13:04:08 -080054 throw std::invalid_argument("data for rust::String is not utf-8");
David Tolnay7db73692019-10-20 14:51:12 -040055 }
56}
57
David Tolnay56082162020-03-01 12:57:33 -080058String::~String() noexcept { cxxbridge01$rust_string$drop(this); }
David Tolnay7db73692019-10-20 14:51:12 -040059
David Tolnay56082162020-03-01 12:57:33 -080060String::operator std::string() const {
David Tolnay7db73692019-10-20 14:51:12 -040061 return std::string(this->data(), this->size());
62}
63
David Tolnay56082162020-03-01 12:57:33 -080064String &String::operator=(const String &other) noexcept {
David Tolnay7db73692019-10-20 14:51:12 -040065 if (this != &other) {
David Tolnaye43b7372020-01-08 08:46:20 -080066 cxxbridge01$rust_string$drop(this);
67 cxxbridge01$rust_string$clone(this, other);
David Tolnay7db73692019-10-20 14:51:12 -040068 }
69 return *this;
70}
71
David Tolnay56082162020-03-01 12:57:33 -080072String &String::operator=(String &&other) noexcept {
David Tolnay7db73692019-10-20 14:51:12 -040073 if (this != &other) {
David Tolnaye43b7372020-01-08 08:46:20 -080074 cxxbridge01$rust_string$drop(this);
David Tolnay7db73692019-10-20 14:51:12 -040075 this->repr = other.repr;
David Tolnaye43b7372020-01-08 08:46:20 -080076 cxxbridge01$rust_string$new(&other);
David Tolnay7db73692019-10-20 14:51:12 -040077 }
78 return *this;
79}
80
David Tolnay56082162020-03-01 12:57:33 -080081const char *String::data() const noexcept {
David Tolnaye43b7372020-01-08 08:46:20 -080082 return cxxbridge01$rust_string$ptr(this);
David Tolnay7db73692019-10-20 14:51:12 -040083}
84
David Tolnay56082162020-03-01 12:57:33 -080085size_t String::size() const noexcept {
David Tolnaye43b7372020-01-08 08:46:20 -080086 return cxxbridge01$rust_string$len(this);
David Tolnay7db73692019-10-20 14:51:12 -040087}
88
David Tolnay56082162020-03-01 12:57:33 -080089size_t String::length() const noexcept {
David Tolnaye43b7372020-01-08 08:46:20 -080090 return cxxbridge01$rust_string$len(this);
David Tolnay7db73692019-10-20 14:51:12 -040091}
92
David Tolnay56082162020-03-01 12:57:33 -080093std::ostream &operator<<(std::ostream &os, const String &s) {
David Tolnay7db73692019-10-20 14:51:12 -040094 os.write(s.data(), s.size());
95 return os;
96}
97
David Tolnay69fe4c22020-03-01 13:57:24 -080098Str::Str() noexcept : repr(Repr{reinterpret_cast<const char *>(this), 0}) {}
David Tolnay7db73692019-10-20 14:51:12 -040099
David Tolnay09dbe752020-03-01 13:00:40 -0800100Str::Str(const char *s) : repr(Repr{s, strlen(s)}) {
David Tolnaye43b7372020-01-08 08:46:20 -0800101 if (!cxxbridge01$rust_str$valid(this->repr.ptr, this->repr.len)) {
David Tolnay750755e2020-03-01 13:04:08 -0800102 throw std::invalid_argument("data for rust::Str is not utf-8");
David Tolnay7db73692019-10-20 14:51:12 -0400103 }
104}
105
David Tolnay09dbe752020-03-01 13:00:40 -0800106Str::Str(const std::string &s) : repr(Repr{s.data(), s.length()}) {
David Tolnaye43b7372020-01-08 08:46:20 -0800107 if (!cxxbridge01$rust_str$valid(this->repr.ptr, this->repr.len)) {
David Tolnay750755e2020-03-01 13:04:08 -0800108 throw std::invalid_argument("data for rust::Str is not utf-8");
David Tolnay7db73692019-10-20 14:51:12 -0400109 }
110}
111
David Tolnay09dbe752020-03-01 13:00:40 -0800112Str::Str(const Str &) noexcept = default;
David Tolnay7db73692019-10-20 14:51:12 -0400113
David Tolnay09dbe752020-03-01 13:00:40 -0800114Str &Str::operator=(Str other) noexcept {
David Tolnay7db73692019-10-20 14:51:12 -0400115 this->repr = other.repr;
116 return *this;
117}
118
David Tolnay09dbe752020-03-01 13:00:40 -0800119Str::operator std::string() const {
David Tolnay7db73692019-10-20 14:51:12 -0400120 return std::string(this->data(), this->size());
121}
122
David Tolnay09dbe752020-03-01 13:00:40 -0800123const char *Str::data() const noexcept { return this->repr.ptr; }
David Tolnay7db73692019-10-20 14:51:12 -0400124
David Tolnay09dbe752020-03-01 13:00:40 -0800125size_t Str::size() const noexcept { return this->repr.len; }
David Tolnay7db73692019-10-20 14:51:12 -0400126
David Tolnay09dbe752020-03-01 13:00:40 -0800127size_t Str::length() const noexcept { return this->repr.len; }
David Tolnay7db73692019-10-20 14:51:12 -0400128
David Tolnay09dbe752020-03-01 13:00:40 -0800129Str::Str(Repr repr_) noexcept : repr(repr_) {}
David Tolnay7db73692019-10-20 14:51:12 -0400130
David Tolnay09dbe752020-03-01 13:00:40 -0800131Str::operator Repr() noexcept { return this->repr; }
David Tolnay7db73692019-10-20 14:51:12 -0400132
David Tolnay09dbe752020-03-01 13:00:40 -0800133std::ostream &operator<<(std::ostream &os, const Str &s) {
David Tolnay7db73692019-10-20 14:51:12 -0400134 os.write(s.data(), s.size());
135 return os;
136}
137
David Tolnay69fe4c22020-03-01 13:57:24 -0800138} // namespace cxxbridge01
David Tolnay750755e2020-03-01 13:04:08 -0800139} // namespace rust
David Tolnay7db73692019-10-20 14:51:12 -0400140
141extern "C" {
David Tolnaye43b7372020-01-08 08:46:20 -0800142void cxxbridge01$unique_ptr$std$string$null(
David Tolnay7db73692019-10-20 14:51:12 -0400143 std::unique_ptr<std::string> *ptr) noexcept {
144 new (ptr) std::unique_ptr<std::string>();
145}
David Tolnaye43b7372020-01-08 08:46:20 -0800146void cxxbridge01$unique_ptr$std$string$new(std::unique_ptr<std::string> *ptr,
David Tolnay7db73692019-10-20 14:51:12 -0400147 std::string *value) noexcept {
148 new (ptr) std::unique_ptr<std::string>(new std::string(std::move(*value)));
149}
David Tolnaye43b7372020-01-08 08:46:20 -0800150void cxxbridge01$unique_ptr$std$string$raw(std::unique_ptr<std::string> *ptr,
David Tolnay7db73692019-10-20 14:51:12 -0400151 std::string *raw) noexcept {
152 new (ptr) std::unique_ptr<std::string>(raw);
153}
David Tolnaye43b7372020-01-08 08:46:20 -0800154const std::string *cxxbridge01$unique_ptr$std$string$get(
David Tolnay7db73692019-10-20 14:51:12 -0400155 const std::unique_ptr<std::string> &ptr) noexcept {
156 return ptr.get();
157}
David Tolnaye43b7372020-01-08 08:46:20 -0800158std::string *cxxbridge01$unique_ptr$std$string$release(
David Tolnay7db73692019-10-20 14:51:12 -0400159 std::unique_ptr<std::string> &ptr) noexcept {
160 return ptr.release();
161}
David Tolnaye43b7372020-01-08 08:46:20 -0800162void cxxbridge01$unique_ptr$std$string$drop(
David Tolnay7db73692019-10-20 14:51:12 -0400163 std::unique_ptr<std::string> *ptr) noexcept {
164 ptr->~unique_ptr();
165}
166} // extern "C"