inline int64_t dynamic::asInt() const { return asImpl<int64_t>(); }
inline bool dynamic::asBool() const { return asImpl<bool>(); }
+inline const fbstring& dynamic::getString() const { return get<fbstring>(); }
+inline double dynamic::getDouble() const { return get<double>(); }
+inline int64_t dynamic::getInt() const { return get<int64_t>(); }
+inline bool dynamic::getBool() const { return get<bool>(); }
+
+inline fbstring& dynamic::getString() { return get<fbstring>(); }
+inline double& dynamic::getDouble() { return get<double>(); }
+inline int64_t& dynamic::getInt() { return get<int64_t>(); }
+inline bool& dynamic::getBool() { return get<bool>(); }
+
inline const char* dynamic::data() const { return get<fbstring>().data(); }
inline const char* dynamic::c_str() const { return get<fbstring>().c_str(); }
+inline StringPiece dynamic::stringPiece() const { return get<fbstring>(); }
template<class T>
struct dynamic::CompareOp {
int64_t asInt() const;
bool asBool() const;
+ /*
+ * Extract the value stored in this dynamic without type conversion.
+ *
+ * These will throw a TypeError if the dynamic has a different type.
+ */
+ const fbstring& getString() const;
+ double getDouble() const;
+ int64_t getInt() const;
+ bool getBool() const;
+ fbstring& getString();
+ double& getDouble();
+ int64_t& getInt();
+ bool& getBool();
+
/*
* It is occasionally useful to access a string's internal pointer
* directly, without the type conversion of `asString()`.
*/
const char* data() const;
const char* c_str() const;
+ StringPiece stringPiece() const;
/*
* Returns: true if this dynamic is null, an empty array, an empty
#include <folly/json.h>
using folly::dynamic;
+using folly::TypeError;
TEST(Dynamic, ObjectBasics) {
dynamic obj = dynamic::object("a", false);
TEST(Dynamic, StringPtrs) {
dynamic str = "12.0";
dynamic num = 12.0;
+ dynamic nullStr = folly::parseJson("\"foo\\u0000bar\"");
EXPECT_EQ(0, strcmp(str.c_str(), "12.0"));
EXPECT_EQ(0, strncmp(str.data(), "12.0", str.asString().length()));
+ EXPECT_EQ(str.stringPiece(), "12.0");
- EXPECT_ANY_THROW(num.c_str());
- EXPECT_ANY_THROW(num.data());
+ EXPECT_THROW(num.c_str(), TypeError);
+ EXPECT_THROW(num.data(), TypeError);
+ EXPECT_THROW(num.stringPiece(), TypeError);
+
+ EXPECT_EQ(nullStr.stringPiece(), folly::StringPiece("foo\0bar", 7));
+
+ nullStr.getString()[3] = '|';
+ EXPECT_EQ(nullStr.stringPiece(), "foo|bar");
}
TEST(Dynamic, FormattedIO) {
EXPECT_EQ(from(arr) | take(3) | member(&dynamic::asInt) | sum, 6);
}
+TEST(Dynamic, Getters) {
+ dynamic dStr = folly::parseJson("\"foo\\u0000bar\"");
+ dynamic dInt = 1;
+ dynamic dDouble = 0.5;
+ dynamic dBool = true;
+
+ EXPECT_EQ(dStr.getString(), std::string("foo\0bar", 7));
+ EXPECT_EQ(dInt.getInt(), 1);
+ EXPECT_EQ(dDouble.getDouble(), 0.5);
+ EXPECT_EQ(dBool.getBool(), true);
+
+ dStr.getString()[3] = '|';
+ EXPECT_EQ(dStr.getString(), "foo|bar");
+
+ dInt.getInt() = 2;
+ EXPECT_EQ(dInt.getInt(), 2);
+
+ dDouble.getDouble() = 0.7;
+ EXPECT_EQ(dDouble.getDouble(), 0.7);
+
+ dBool.getBool() = false;
+ EXPECT_EQ(dBool.getBool(), false);
+
+ EXPECT_THROW(dStr.getInt(), TypeError);
+ EXPECT_THROW(dStr.getDouble(), TypeError);
+ EXPECT_THROW(dStr.getBool(), TypeError);
+
+ EXPECT_THROW(dInt.getString(), TypeError);
+ EXPECT_THROW(dInt.getDouble(), TypeError);
+ EXPECT_THROW(dInt.getBool(), TypeError);
+
+ EXPECT_THROW(dDouble.getString(), TypeError);
+ EXPECT_THROW(dDouble.getInt(), TypeError);
+ EXPECT_THROW(dDouble.getBool(), TypeError);
+
+ EXPECT_THROW(dBool.getString(), TypeError);
+ EXPECT_THROW(dBool.getInt(), TypeError);
+ EXPECT_THROW(dBool.getDouble(), TypeError);
+}
+
int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
gflags::ParseCommandLineFlags(&argc, &argv, true);