@@ -118,8 +118,37 @@ template <> struct nullness<pgvector::SparseVector> : no_null<pgvector::SparseVe
118118template <> struct string_traits <pgvector::SparseVector> {
119119 static constexpr bool converts_to_string{true };
120120
121- // TODO add from_string
122- static constexpr bool converts_from_string{false };
121+ static constexpr bool converts_from_string{true };
122+
123+ static pgvector::SparseVector from_string (std::string_view text) {
124+ if (text.size () < 4 || text.front () != ' {' ) {
125+ throw conversion_error (" Malformed sparsevec literal" );
126+ }
127+
128+ size_t n = text.find (" }/" , 1 );
129+ if (n == std::string_view::npos) {
130+ throw conversion_error (" Malformed sparsevec literal" );
131+ }
132+
133+ std::vector<int > indices;
134+ std::vector<float > values;
135+ std::istringstream ss (std::string (text.substr (1 , n)));
136+ while (ss.good ()) {
137+ std::string substr;
138+ std::getline (ss, substr, ' ,' );
139+
140+ size_t ne = substr.find (" :" );
141+ if (ne == std::string::npos) {
142+ throw conversion_error (" Malformed sparsevec literal" );
143+ }
144+
145+ indices.push_back (std::stoi (substr.substr (0 , ne)) - 1 );
146+ values.push_back (std::stof (substr.substr (ne + 1 )));
147+ }
148+
149+ int dimensions = std::stoi (std::string (text.substr (n + 2 )));
150+ return pgvector::SparseVector (dimensions, indices, values);
151+ }
123152
124153 static zview to_buf (char * begin, char * end, const pgvector::SparseVector& value) {
125154 char *const next = into_buf (begin, end, value);
0 commit comments