Merge "Make talonfx use static flatbuffer api"
diff --git a/.clang-format b/.clang-format
index 7e45a49..fcdaf0d 100644
--- a/.clang-format
+++ b/.clang-format
@@ -11,7 +11,7 @@
     - Regex:     '^<(cxx|Halide|HalidBuffer|lzma|node|v8|osqp|oscqp\+\+|snappy|snappy-sinksource).h>$'
       Priority:  3
     # Force some more third-party headers to be appropriately categorized.
-    - Regex:     '^(<|")(absl|ceres|ctre|Eigen|external|FRC_NetworkCommunication|foxglove|flatbuffers|glib-2.0|glog|gflags|gmock|gtest|google|libusb-1.0|lz4|opencv2|openssl|rawrtcc|sanitizer|nlohmann|third_party|wpi)/.*(>|")$'
+    - Regex:     '^(<|")(absl|ceres|ctre|Eigen|external|FRC_NetworkCommunication|foxglove|flatbuffers|glib-2.0|glog|gflags|gmock|gtest|google|libusb-1.0|lz4|opencv2|openssl|rawrtcc|sanitizer|nlohmann|third_party|wpi|tl)/.*(>|")$'
       Priority:  3
     # The default regexes. For some reason, if we don't specify them here, then
     # clang-format will overwrite them with the custom ones we specify above.
diff --git a/WORKSPACE b/WORKSPACE
index ec5e8e0..3b2eb57 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -1655,3 +1655,17 @@
     sha256 = "b106b3b975d3cf3ad3fcd5e4be7409f6095e1d531346a90c4ad6bdb7da1d08a5",
     url = "https://software.frc971.org/Build-Dependencies/2023_calibrate_multi_cameras_data.tar.gz",
 )
+
+http_archive(
+    name = "com_github_tartanllama_expected",
+    build_file_content = """
+cc_library(
+  name = "com_github_tartanllama_expected",
+  srcs = ["include/tl/expected.hpp"],
+  includes = ["include"],
+  visibility = ["//visibility:public"],
+)""",
+    sha256 = "1db357f46dd2b24447156aaf970c4c40a793ef12a8a9c2ad9e096d9801368df6",
+    strip_prefix = "expected-1.1.0",
+    url = "https://github.com/TartanLlama/expected/archive/refs/tags/v1.1.0.tar.gz",
+)
diff --git a/aos/flatbuffers.h b/aos/flatbuffers.h
index ed9c8ac..a299fe9 100644
--- a/aos/flatbuffers.h
+++ b/aos/flatbuffers.h
@@ -529,6 +529,15 @@
   std::shared_ptr<absl::Span<uint8_t>> span_;
 };
 
+// The regular flatbuffer API makes it surprisingly irritating to unpack an
+// Object into an ObjectT without a bunch of extra lines.
+template <typename T>
+T::NativeTableType UnpackFlatbuffer(const T *fbs) {
+  typename T::NativeTableType object;
+  fbs->UnPackTo(&object);
+  return object;
+}
+
 }  // namespace aos
 
 #endif  // AOS_FLATBUFFERS_H_
diff --git a/aos/flatbuffers_test.cc b/aos/flatbuffers_test.cc
index dbbe817..333d5d7 100644
--- a/aos/flatbuffers_test.cc
+++ b/aos/flatbuffers_test.cc
@@ -23,6 +23,16 @@
   EXPECT_FALSE(empty.Verify());
 }
 
+// Test that the UnpackFlatbuffer builds & works.
+TEST(FlatbufferTest, UnpackFlatbuffer) {
+  const FlatbufferDetachedBuffer<Location> fb =
+      JsonToFlatbuffer<Location>("{\"name\": \"abc\", \"frequency\": 971}");
+
+  LocationT object = UnpackFlatbuffer(&fb.message());
+  EXPECT_EQ("abc", object.name);
+  EXPECT_EQ(971, object.frequency);
+}
+
 // Tests the ability to map a flatbuffer on disk to memory
 TEST(FlatbufferMMapTest, Verify) {
   FlatbufferDetachedBuffer<Configuration> fb =