From e49575d4bf1bc6408952d6b469d9b80d53729263 Mon Sep 17 00:00:00 2001
From: Qinfan Wu <wqfish@fb.com>
Date: Sun, 28 May 2017 13:49:28 -0700
Subject: [PATCH] Fix tryTo to support conversion to enumerations

Summary:
[Folly] Fix `tryTo` to support conversion to enumerations.

`tryTo` should return `Expected<Tgt, ConversionCode>` instead of `Tgt`.

Reviewed By: yfeldblum

Differential Revision: D5144706

fbshipit-source-id: cd23f3cf75de7c5a26bc569f3cb47fff360f6e2a
---
 folly/Conv.h            |  2 +-
 folly/test/ConvTest.cpp | 12 ++++++++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/folly/Conv.h b/folly/Conv.h
index 22cc8ac4..6cc32705 100644
--- a/folly/Conv.h
+++ b/folly/Conv.h
@@ -1536,7 +1536,7 @@ tryTo(const Src& value) {
 template <class Tgt, class Src>
 typename std::enable_if<
     std::is_enum<Tgt>::value && !std::is_same<Src, Tgt>::value,
-    Tgt>::type
+    Expected<Tgt, ConversionCode>>::type
 tryTo(const Src& value) {
   using I = typename std::underlying_type<Tgt>::type;
   return tryTo<I>(value).then([](I i) { return static_cast<Tgt>(i); });
diff --git a/folly/test/ConvTest.cpp b/folly/test/ConvTest.cpp
index 5f33cf48..646f8a13 100644
--- a/folly/test/ConvTest.cpp
+++ b/folly/test/ConvTest.cpp
@@ -1061,6 +1061,18 @@ TEST(Conv, TryStringToInt) {
   EXPECT_EQ(rv2.value(), 4711);
 }
 
+TEST(Conv, TryStringToEnum) {
+  enum class A { x = 42, y = 420, z = 65 };
+  auto rv1 = folly::tryTo<A>("1000000000000000000000000000000");
+  EXPECT_FALSE(rv1.hasValue());
+  auto rv2 = folly::tryTo<A>("42");
+  EXPECT_TRUE(rv2.hasValue());
+  EXPECT_EQ(A::x, rv2.value());
+  auto rv3 = folly::tryTo<A>("50");
+  EXPECT_TRUE(rv3.hasValue());
+  EXPECT_EQ(static_cast<A>(50), rv3.value());
+}
+
 TEST(Conv, TryStringToFloat) {
   auto rv1 = folly::tryTo<float>("");
   EXPECT_FALSE(rv1.hasValue());
-- 
2.34.1