Skip to content

Commit fbbe5b6

Browse files
committed
Special-ify some HTTP types
Rather than having HTTP types participate specialy in the case-conversion infra, this commit (authored by Codex, with message by me) makes them into "special" types with double-underscore variant and field names, and with special recognition by codegen and schema validation.
1 parent 757990a commit fbbe5b6

12 files changed

Lines changed: 239 additions & 117 deletions

File tree

crates/codegen/src/cpp.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ impl<'opts> Cpp<'opts> {
9090
AlgebraicTypeUse::TimeDuration => write!(output, "__sdk::TimeDuration"),
9191
AlgebraicTypeUse::ScheduleAt => write!(output, "__sdk::ScheduleAt"),
9292
AlgebraicTypeUse::Uuid => write!(output, "__sdk::Uuid"),
93+
AlgebraicTypeUse::HttpRequestAndBody | AlgebraicTypeUse::HttpResponseAndBody => {
94+
unimplemented!("Http request/response types are not supported in C++ output")
95+
}
9396
AlgebraicTypeUse::Unit => write!(output, "std::monostate"),
9497
AlgebraicTypeUse::Never => write!(output, "std::monostate"),
9598
AlgebraicTypeUse::Ref(type_ref) => {

crates/codegen/src/csharp.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,6 +1231,9 @@ fn ty_fmt<'a>(module: &'a ModuleDef, ty: &'a AlgebraicTypeUse) -> impl fmt::Disp
12311231
PrimitiveType::F32 => "float",
12321232
PrimitiveType::F64 => "double",
12331233
}),
1234+
AlgebraicTypeUse::HttpRequestAndBody | AlgebraicTypeUse::HttpResponseAndBody => {
1235+
unimplemented!("Http request/response types are not supported in C# output")
1236+
}
12341237
AlgebraicTypeUse::Never => unimplemented!(),
12351238
})
12361239
}
@@ -1276,6 +1279,9 @@ fn ty_fmt_with_ns<'a>(module: &'a ModuleDef, ty: &'a AlgebraicTypeUse, namespace
12761279
PrimitiveType::F32 => "float",
12771280
PrimitiveType::F64 => "double",
12781281
}),
1282+
AlgebraicTypeUse::HttpRequestAndBody | AlgebraicTypeUse::HttpResponseAndBody => {
1283+
unimplemented!("Http request/response types are not supported in C# output")
1284+
}
12791285
AlgebraicTypeUse::Never => unimplemented!(),
12801286
})
12811287
}
@@ -1307,6 +1313,9 @@ fn default_init(ctx: &TypespaceForGenerate, ty: &AlgebraicTypeUse) -> Option<&'s
13071313
| AlgebraicTypeUse::Timestamp
13081314
| AlgebraicTypeUse::TimeDuration
13091315
| AlgebraicTypeUse::Uuid => None,
1316+
AlgebraicTypeUse::HttpRequestAndBody | AlgebraicTypeUse::HttpResponseAndBody => {
1317+
unimplemented!("Http request/response types are not supported in C# output")
1318+
}
13101319
AlgebraicTypeUse::Never => unimplemented!("never types are not yet supported in C# output"),
13111320
}
13121321
}

crates/codegen/src/rust.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,8 @@ pub fn write_type<W: Write>(module: &ModuleDef, out: &mut W, ty: &AlgebraicTypeU
826826
AlgebraicTypeUse::Timestamp => write!(out, "__sdk::Timestamp")?,
827827
AlgebraicTypeUse::TimeDuration => write!(out, "__sdk::TimeDuration")?,
828828
AlgebraicTypeUse::Uuid => write!(out, "__sdk::Uuid")?,
829+
AlgebraicTypeUse::HttpRequestAndBody => write!(out, "__sdk::HttpRequestAndBody")?,
830+
AlgebraicTypeUse::HttpResponseAndBody => write!(out, "__sdk::HttpResponseAndBody")?,
829831
AlgebraicTypeUse::ScheduleAt => write!(out, "__sdk::ScheduleAt")?,
830832
AlgebraicTypeUse::Option(inner_ty) => {
831833
write!(out, "Option::<")?;

crates/codegen/src/typescript.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,7 @@ fn write_type_builder<W: Write>(module: &ModuleDef, out: &mut W, ty: &AlgebraicT
789789
AlgebraicTypeUse::TimeDuration => write!(out, "__t.timeDuration()")?,
790790
AlgebraicTypeUse::ScheduleAt => write!(out, "__t.scheduleAt()")?,
791791
AlgebraicTypeUse::Uuid => write!(out, "__t.uuid()")?,
792+
AlgebraicTypeUse::HttpRequestAndBody | AlgebraicTypeUse::HttpResponseAndBody => unimplemented!(),
792793
AlgebraicTypeUse::Option(inner_ty) => {
793794
write!(out, "__t.option(")?;
794795
write_type_builder(module, out, inner_ty)?;
@@ -916,6 +917,7 @@ fn needs_parens_within_array(ty: &AlgebraicTypeUse) -> bool {
916917
AlgebraicTypeUse::ScheduleAt | AlgebraicTypeUse::Option(_) | AlgebraicTypeUse::Result { .. } => {
917918
true
918919
}
920+
AlgebraicTypeUse::HttpRequestAndBody | AlgebraicTypeUse::HttpResponseAndBody => unimplemented!(),
919921
}
920922
}
921923

@@ -934,6 +936,7 @@ pub fn write_type<W: Write>(
934936
AlgebraicTypeUse::Timestamp => write!(out, "__Infer<typeof __t.timestamp()>")?,
935937
AlgebraicTypeUse::TimeDuration => write!(out, "__Infer<typeof __t.timeDuration()>")?,
936938
AlgebraicTypeUse::Uuid => write!(out, "__Uuid")?,
939+
AlgebraicTypeUse::HttpRequestAndBody | AlgebraicTypeUse::HttpResponseAndBody => unimplemented!(),
937940
AlgebraicTypeUse::ScheduleAt => write!(
938941
out,
939942
"{{ tag: \"Interval\", value: __Infer<typeof __t.timeDuration()> }} | {{ tag: \"Time\", value: __Infer<typeof __t.timestamp()> }}"

crates/codegen/src/unrealcpp.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4163,6 +4163,9 @@ fn get_array_element_type_name(module: &ModuleDef, elem: &AlgebraicTypeUse) -> S
41634163
AlgebraicTypeUse::Timestamp => "Timestamp".to_string(),
41644164
AlgebraicTypeUse::TimeDuration => "TimeDuration".to_string(),
41654165
AlgebraicTypeUse::Uuid => "Uuid".to_string(),
4166+
AlgebraicTypeUse::HttpRequestAndBody | AlgebraicTypeUse::HttpResponseAndBody => {
4167+
unimplemented!("Http request/response types are not supported in Unreal output")
4168+
}
41664169
AlgebraicTypeUse::ScheduleAt => "ScheduleAt".to_string(),
41674170
AlgebraicTypeUse::Ref(r) => type_ref_name(module, *r),
41684171
AlgebraicTypeUse::Option(nested_inner) => {
@@ -4203,6 +4206,9 @@ fn get_optional_type_name(module: &ModuleDef, inner: &AlgebraicTypeUse) -> Strin
42034206
AlgebraicTypeUse::Timestamp => "OptionalTimestamp".to_string(),
42044207
AlgebraicTypeUse::TimeDuration => "OptionalTimeDuration".to_string(),
42054208
AlgebraicTypeUse::Uuid => "OptionalUuid".to_string(),
4209+
AlgebraicTypeUse::HttpRequestAndBody | AlgebraicTypeUse::HttpResponseAndBody => {
4210+
unimplemented!("Http request/response types are not supported in Unreal output")
4211+
}
42064212
AlgebraicTypeUse::ScheduleAt => "OptionalScheduleAt".to_string(),
42074213
AlgebraicTypeUse::Array(elem) => {
42084214
// Generate specific optional array types based on element type
@@ -4523,6 +4529,9 @@ fn get_type_name_for_result(module: &ModuleDef, ty: &AlgebraicTypeUse) -> String
45234529
AlgebraicTypeUse::TimeDuration => "TimeDuration".to_string(),
45244530
AlgebraicTypeUse::ScheduleAt => "ScheduleAt".to_string(),
45254531
AlgebraicTypeUse::Uuid => "Uuid".to_string(),
4532+
AlgebraicTypeUse::HttpRequestAndBody | AlgebraicTypeUse::HttpResponseAndBody => {
4533+
unimplemented!("Http request/response types are not supported in Unreal output")
4534+
}
45264535
AlgebraicTypeUse::Unit => "Unit".to_string(),
45274536
AlgebraicTypeUse::Array(elem) => {
45284537
// Generate specific array types based on element type
@@ -4918,6 +4927,9 @@ fn should_pass_by_value_in_delegate(_module: &ModuleDef, ty: &AlgebraicTypeUse)
49184927
AlgebraicTypeUse::Timestamp => false, // FSpacetimeDBTimestamp is a USTRUCT
49194928
AlgebraicTypeUse::TimeDuration => false, // FSpacetimeDBTimeDuration is a USTRUCT
49204929
AlgebraicTypeUse::Uuid => false, // FSpacetimeDBUuid is a USTRUCT
4930+
AlgebraicTypeUse::HttpRequestAndBody | AlgebraicTypeUse::HttpResponseAndBody => {
4931+
unimplemented!("Http request/response types are not supported in Unreal output")
4932+
}
49214933
// Custom structs/enums use const references
49224934
AlgebraicTypeUse::Ref(_) => false,
49234935
AlgebraicTypeUse::Array(_) => false, // Arrays use const references
@@ -4961,6 +4973,9 @@ fn is_blueprintable(module: &ModuleDef, ty: &AlgebraicTypeUse) -> bool {
49614973
AlgebraicTypeUse::Timestamp => true,
49624974
AlgebraicTypeUse::TimeDuration => true,
49634975
AlgebraicTypeUse::Uuid => true,
4976+
AlgebraicTypeUse::HttpRequestAndBody | AlgebraicTypeUse::HttpResponseAndBody => {
4977+
unimplemented!("Http request/response types are not supported in Unreal output")
4978+
}
49644979
AlgebraicTypeUse::ScheduleAt => true, // ScheduleAt is blueprintable as a property (TObjectPtr)
49654980
AlgebraicTypeUse::Unit => true,
49664981
AlgebraicTypeUse::Ref(r) => {
@@ -5000,6 +5015,9 @@ fn is_type_blueprintable_for_delegates(module: &ModuleDef, ty: &AlgebraicTypeUse
50005015
AlgebraicTypeUse::Timestamp => true,
50015016
AlgebraicTypeUse::TimeDuration => true,
50025017
AlgebraicTypeUse::Uuid => true,
5018+
AlgebraicTypeUse::HttpRequestAndBody | AlgebraicTypeUse::HttpResponseAndBody => {
5019+
unimplemented!("Http request/response types are not supported in Unreal output")
5020+
}
50035021
AlgebraicTypeUse::ScheduleAt => true,
50045022
AlgebraicTypeUse::Unit => true,
50055023
AlgebraicTypeUse::Ref(r) => {
@@ -5428,6 +5446,9 @@ fn cpp_ty_fmt_impl<'a>(
54285446
AlgebraicTypeUse::Timestamp => f.write_str("FSpacetimeDBTimestamp"),
54295447
AlgebraicTypeUse::TimeDuration => f.write_str("FSpacetimeDBTimeDuration"),
54305448
AlgebraicTypeUse::Uuid => f.write_str("FSpacetimeDBUuid"),
5449+
AlgebraicTypeUse::HttpRequestAndBody | AlgebraicTypeUse::HttpResponseAndBody => {
5450+
unimplemented!("Http request/response types are not supported in Unreal output")
5451+
}
54315452
AlgebraicTypeUse::ScheduleAt => f.write_str("FSpacetimeDBScheduleAt"),
54325453
AlgebraicTypeUse::Unit => f.write_str("FSpacetimeDBUnit"),
54335454

@@ -5497,6 +5518,9 @@ fn cpp_ty_init_fmt_impl(module: &ModuleDef, ty: &AlgebraicTypeUse) -> String {
54975518
AlgebraicTypeUse::TimeDuration => String::new(),
54985519
AlgebraicTypeUse::ScheduleAt => String::new(),
54995520
AlgebraicTypeUse::Uuid => String::new(),
5521+
AlgebraicTypeUse::HttpRequestAndBody | AlgebraicTypeUse::HttpResponseAndBody => {
5522+
unimplemented!("Http request/response types are not supported in Unreal output")
5523+
}
55005524
AlgebraicTypeUse::Unit => String::new(),
55015525
// --------- references to user-defined types ---------
55025526
AlgebraicTypeUse::Ref(r) => {
@@ -5560,6 +5584,9 @@ fn collect_includes_for_type(module: &ModuleDef, ty: &AlgebraicTypeUse, out: &mu
55605584
Identity | ConnectionId | Timestamp | TimeDuration | ScheduleAt | Uuid => {
55615585
out.insert("Types/Builtins.h".to_string());
55625586
}
5587+
HttpRequestAndBody | HttpResponseAndBody => {
5588+
unimplemented!("Http request/response types are not supported in Unreal output")
5589+
}
55635590
// Large integer primitives also need Builtins.h (for LargeIntegers.h)
55645591
Primitive(PrimitiveType::I128)
55655592
| Primitive(PrimitiveType::U128)

crates/lib/src/db/raw_def/v10.rs

Lines changed: 4 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -135,18 +135,6 @@ pub struct NameMapping {
135135
pub canonical_name: RawIdentifier,
136136
}
137137

138-
#[derive(Debug, Clone, SpacetimeType)]
139-
#[sats(crate = crate)]
140-
#[cfg_attr(feature = "test", derive(PartialEq, Eq, Ord, PartialOrd))]
141-
pub struct EnumVariantNameMapping {
142-
/// The source name of the containing enum.
143-
pub enum_source_name: RawIdentifier,
144-
/// The source name of the variant.
145-
pub variant_source_name: RawIdentifier,
146-
/// The canonical name of the variant.
147-
pub variant_canonical_name: RawIdentifier,
148-
}
149-
150138
#[derive(Debug, Clone, SpacetimeType)]
151139
#[sats(crate = crate)]
152140
#[cfg_attr(feature = "test", derive(PartialEq, Eq, Ord, PartialOrd))]
@@ -155,7 +143,6 @@ pub enum ExplicitNameEntry {
155143
Table(NameMapping),
156144
Function(NameMapping),
157145
Index(NameMapping),
158-
EnumVariant(EnumVariantNameMapping),
159146
}
160147

161148
#[derive(Debug, Default, Clone, SpacetimeType)]
@@ -196,19 +183,6 @@ impl ExplicitNames {
196183
}));
197184
}
198185

199-
pub fn insert_enum_variant(
200-
&mut self,
201-
enum_source_name: impl Into<RawIdentifier>,
202-
variant_source_name: impl Into<RawIdentifier>,
203-
variant_canonical_name: impl Into<RawIdentifier>,
204-
) {
205-
self.insert(ExplicitNameEntry::EnumVariant(EnumVariantNameMapping {
206-
enum_source_name: enum_source_name.into(),
207-
variant_source_name: variant_source_name.into(),
208-
variant_canonical_name: variant_canonical_name.into(),
209-
}));
210-
}
211-
212186
pub fn merge(&mut self, other: ExplicitNames) {
213187
self.entries.extend(other.entries);
214188
}
@@ -1193,18 +1167,16 @@ impl TypespaceBuilder for RawModuleDefV10Builder {
11931167
if let btree_map::Entry::Occupied(o) = self.type_map.entry(typeid) {
11941168
AlgebraicType::Ref(*o.get())
11951169
} else {
1196-
let (slot_ref, enum_source_name) = {
1170+
let slot_ref = {
11971171
let ts = self.typespace_mut();
11981172
// Bind a fresh alias to the unit type.
11991173
let slot_ref = ts.add(AlgebraicType::unit());
12001174
// Relate `typeid -> fresh alias`.
12011175
self.type_map.insert(typeid, slot_ref);
12021176

12031177
// Alias provided? Relate `name -> slot_ref`.
1204-
let enum_source_name = if let Some(sats_name) = source_name {
1178+
if let Some(sats_name) = source_name {
12051179
let source_name = sats_name_to_scoped_name_v10(sats_name);
1206-
let enum_source_name =
1207-
should_register_enum_variant_names(sats_name).then(|| source_name.source_name.clone());
12081180

12091181
self.types_mut().push(RawTypeDefV10 {
12101182
source_name,
@@ -1215,44 +1187,18 @@ impl TypespaceBuilder for RawModuleDefV10Builder {
12151187
// macro doesn't know about the default ordering yet.
12161188
custom_ordering: true,
12171189
});
1218-
enum_source_name
1219-
} else {
1220-
None
1221-
};
1222-
(slot_ref, enum_source_name)
1190+
}
1191+
slot_ref
12231192
};
12241193

12251194
// Borrow of `v` has ended here, so we can now convince the borrow checker.
12261195
let ty = make_ty(self);
12271196
self.typespace_mut()[slot_ref] = ty;
1228-
let enum_variants = match (&enum_source_name, &self.typespace_mut()[slot_ref]) {
1229-
(Some(enum_source_name), AlgebraicType::Sum(sum)) => Some((
1230-
enum_source_name.clone(),
1231-
sum.variants
1232-
.iter()
1233-
.filter_map(|variant| variant.name().cloned())
1234-
.collect::<Vec<_>>(),
1235-
)),
1236-
_ => None,
1237-
};
1238-
if let Some((enum_source_name, variant_names)) = enum_variants {
1239-
for variant_name in variant_names {
1240-
self.explicit_names_mut().insert_enum_variant(
1241-
enum_source_name.clone(),
1242-
variant_name.clone(),
1243-
variant_name,
1244-
);
1245-
}
1246-
}
12471197
AlgebraicType::Ref(slot_ref)
12481198
}
12491199
}
12501200
}
12511201

1252-
fn should_register_enum_variant_names(sats_name: &str) -> bool {
1253-
matches!(sats_name, "HttpMethod" | "HttpVersion")
1254-
}
1255-
12561202
pub fn reducer_default_ok_return_type() -> AlgebraicType {
12571203
AlgebraicType::unit()
12581204
}

crates/lib/src/http.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,13 @@
1818
//! Instead, if/when we want to add new functionality which requires sending additional information,
1919
//! we'll define a new versioned ABI call which uses new types for interchange.
2020
21-
use spacetimedb_sats::{time_duration::TimeDuration, SpacetimeType};
21+
use crate::de::Deserialize;
22+
use crate::ser::Serialize;
23+
use spacetimedb_sats::{
24+
product_type::{HTTP_BODY_TAG, HTTP_REQUEST_TAG, HTTP_RESPONSE_TAG},
25+
time_duration::TimeDuration,
26+
AlgebraicType, SpacetimeType,
27+
};
2228

2329
/// Represents an HTTP request which can be made from a procedure running in a SpacetimeDB database.
2430
#[derive(Clone, SpacetimeType)]
@@ -170,20 +176,36 @@ impl Response {
170176
///
171177
/// This is used for incoming HTTP route handling where the body bytes are kept separate
172178
/// from the metadata-only [`Request`].
173-
#[derive(Clone, SpacetimeType)]
174-
#[sats(crate = crate, name = "HttpRequestAndBody")]
179+
#[derive(Clone, Serialize, Deserialize)]
175180
pub struct RequestAndBody {
176181
pub request: Request,
177182
pub body: Box<[u8]>,
178183
}
179184

185+
impl SpacetimeType for RequestAndBody {
186+
fn make_type<S: spacetimedb_sats::typespace::TypespaceBuilder>(typespace: &mut S) -> AlgebraicType {
187+
AlgebraicType::product([
188+
(HTTP_REQUEST_TAG, Request::make_type(typespace)),
189+
(HTTP_BODY_TAG, AlgebraicType::array(AlgebraicType::U8)),
190+
])
191+
}
192+
}
193+
180194
/// A response paired with its body bytes.
181195
///
182196
/// This is used for HTTP route handling where the body bytes are kept separate
183197
/// from the metadata-only [`Response`].
184-
#[derive(Clone, SpacetimeType)]
185-
#[sats(crate = crate, name = "HttpResponseAndBody")]
198+
#[derive(Clone, Serialize, Deserialize)]
186199
pub struct ResponseAndBody {
187200
pub response: Response,
188201
pub body: Box<[u8]>,
189202
}
203+
204+
impl SpacetimeType for ResponseAndBody {
205+
fn make_type<S: spacetimedb_sats::typespace::TypespaceBuilder>(typespace: &mut S) -> AlgebraicType {
206+
AlgebraicType::product([
207+
(HTTP_RESPONSE_TAG, Response::make_type(typespace)),
208+
(HTTP_BODY_TAG, AlgebraicType::array(AlgebraicType::U8)),
209+
])
210+
}
211+
}

0 commit comments

Comments
 (0)