@@ -11,7 +11,7 @@ pub mod v3 {
1111
1212 use ruma_common:: {
1313 OwnedDeviceId ,
14- api:: { auth_scheme:: AccessToken , request, response } ,
14+ api:: { auth_scheme:: AccessToken , request} ,
1515 metadata,
1616 } ;
1717
@@ -42,9 +42,18 @@ pub mod v3 {
4242 }
4343
4444 /// Response type for the `update_device` endpoint.
45- #[ response]
46- #[ derive( Default ) ]
47- pub struct Response { }
45+ ///
46+ /// The HTTP status reflects whether a device was created or merely updated:
47+ /// an application service creating a device receives `201 Created`, any
48+ /// other update receives `200 OK` (MSC4190). The body is empty in both
49+ /// cases, so this is hand-written rather than generated by the `response`
50+ /// macro, whose status is fixed.
51+ #[ derive( Clone , Debug , Default ) ]
52+ #[ cfg_attr( not( ruma_unstable_exhaustive_types) , non_exhaustive) ]
53+ pub struct Response {
54+ /// Whether a new device was created rather than an existing one updated.
55+ pub created : bool ,
56+ }
4857
4958 impl Request {
5059 /// Creates a new `Request` with the given device ID.
@@ -54,9 +63,54 @@ pub mod v3 {
5463 }
5564
5665 impl Response {
57- /// Creates an empty `Response` .
66+ /// Creates a `Response` for an updated device (`200 OK`) .
5867 pub fn new ( ) -> Self {
59- Self { }
68+ Self { created : false }
69+ }
70+
71+ /// Creates a `Response` for a newly created device (`201 Created`).
72+ pub fn created ( ) -> Self {
73+ Self { created : true }
74+ }
75+ }
76+
77+ #[ cfg( feature = "server" ) ]
78+ impl ruma_common:: api:: OutgoingResponse for Response {
79+ fn try_into_http_response < T : Default + bytes:: BufMut > (
80+ self ,
81+ ) -> Result < http:: Response < T > , ruma_common:: api:: error:: IntoHttpError > {
82+ let status =
83+ if self . created { http:: StatusCode :: CREATED } else { http:: StatusCode :: OK } ;
84+
85+ let mut response = http:: Response :: builder ( )
86+ . status ( status)
87+ . body ( ruma_common:: serde:: slice_to_buf ( b"{}" ) ) ?;
88+
89+ response
90+ . headers_mut ( )
91+ . insert ( http:: header:: CONTENT_TYPE , ruma_common:: http_headers:: APPLICATION_JSON ) ;
92+
93+ Ok ( response)
94+ }
95+ }
96+
97+ #[ cfg( feature = "client" ) ]
98+ impl ruma_common:: api:: IncomingResponse for Response {
99+ type EndpointError = ruma_common:: api:: error:: Error ;
100+
101+ fn try_from_http_response < T : AsRef < [ u8 ] > > (
102+ response : http:: Response < T > ,
103+ ) -> Result < Self , ruma_common:: api:: error:: FromHttpResponseError < Self :: EndpointError > >
104+ {
105+ if response. status ( ) . as_u16 ( ) >= 400 {
106+ return Err ( ruma_common:: api:: error:: FromHttpResponseError :: Server (
107+ <Self :: EndpointError as ruma_common:: api:: EndpointError >:: from_http_response (
108+ response,
109+ ) ,
110+ ) ) ;
111+ }
112+
113+ Ok ( Self { created : response. status ( ) == http:: StatusCode :: CREATED } )
60114 }
61115 }
62116}
0 commit comments