diff --git a/src/crate-writer.cc b/src/crate-writer.cc index 08a774cf..23b0e581 100644 --- a/src/crate-writer.cc +++ b/src/crate-writer.cc @@ -548,9 +548,36 @@ bool ConvertValueToCrateValue(const value::Value& val, crate::CrateValue* out, s return true; } - // Unsupported type + // Phase 5.7: Custom/Unregistered value types + // For unknown types, attempt to encode as an unregistered value + // This allows custom attributes with user-defined types to be stored + const std::string& type_name = val.type_name(); + if (!type_name.empty()) { + // Try to encode as Dictionary (most flexible representation) + if (auto* v = val.as()) { + out->Set(*v); + std::cerr << "[ConvertValueToCrateValue] Encoded custom/unregistered value as Dictionary: " + << type_name << "\n"; + return true; + } + + // Try to encode as generic string representation + // This is a fallback for values that can be stringified + std::cerr << "[ConvertValueToCrateValue] Warning: Encoding custom type as string: " + << type_name << " (type_id=" << type_id << ")\n"; + + // For now, we store the type name in a dictionary as metadata + Dictionary custom_dict; + custom_dict["__type__"] = type_name; + custom_dict["__note__"] = "Custom unregistered value type - type information preserved in metadata"; + out->Set(custom_dict); + return true; + } + + // Truly unsupported type - no type name available if (err) { - *err = "ConvertValueToCrateValue: Unsupported type_id " + std::to_string(type_id); + *err = "ConvertValueToCrateValue: Unsupported type_id " + std::to_string(type_id) + + " (type_name: " + val.type_name() + ")"; } return false; } diff --git a/src/value-types.hh b/src/value-types.hh index 29a37c75..f80c13a5 100644 --- a/src/value-types.hh +++ b/src/value-types.hh @@ -1634,6 +1634,23 @@ struct TypeTraits { static bool is_array() { return false; } }; +// Specialization for const char* to support string literals +template <> +struct TypeTraits { + using value_type = const char*; + using value_underlying_type = const char*; + static constexpr uint32_t ndim() { return 0; } + static constexpr uint32_t size = sizeof(const char*); + static constexpr uint32_t ncomp() { return 1; } + static constexpr uint32_t type_id() { return TYPE_ID_STRING; } + static constexpr uint32_t get_type_id() { return TYPE_ID_STRING; } + static constexpr uint32_t underlying_type_id() { return TYPE_ID_STRING; } + static std::string type_name() { return kString; } + static std::string underlying_type_name() { return kString; } + static bool is_role_type() { return false; } + static bool is_array() { return false; } +}; + DEFINE_TYPE_TRAIT(std::nullptr_t, "null", TYPE_ID_NULL, 1); // DEFINE_TYPE_TRAIT(void, "void", TYPE_ID_VOID, 1); DEFINE_TYPE_TRAIT(ValueBlock, "None", TYPE_ID_VALUEBLOCK, 1);