Skip to content

Commit 6b512f4

Browse files
committed
much cleaner json response handling
1 parent 1a87377 commit 6b512f4

1 file changed

Lines changed: 31 additions & 43 deletions

File tree

fastmask/main.go

Lines changed: 31 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ const (
3535
_maskedEmailSetMethod = "MaskedEmail/set"
3636

3737
// JMAP response keys
38-
_jmapCreatedKey = "created"
39-
_jmapEmailKey = "email"
4038
_jmapStateEnabled = "enabled"
4139

4240
// Request identifiers
@@ -98,7 +96,15 @@ type FastmailMaskedEmailRequest struct {
9896
}
9997

10098
type FastmailMaskedEmailResponse struct {
101-
MethodResponses [][]any `json:"methodResponses"`
99+
MethodResponses []jsontext.Value `json:"methodResponses"`
100+
}
101+
102+
type MaskedEmailSetResponseDetail struct {
103+
Email string `json:"email"`
104+
}
105+
106+
type MaskedEmailSetResponse struct {
107+
Created map[string]MaskedEmailSetResponseDetail `json:"created"`
102108
}
103109

104110
type FastmaskResponse struct {
@@ -244,70 +250,52 @@ func createMaskedEmail(fastmailId *FastmailIdentity, domain string, token Secure
244250
if err != nil {
245251
return nil, err
246252
}
247-
body := string(bodyBytes)
248-
249253
if resp.StatusCode != 200 {
254+
body := string(bodyBytes)
250255
return nil, fmt.Errorf("server returned status code %d: %s", resp.StatusCode, body)
251256
}
252257

253258
var fastmailResponse FastmailMaskedEmailResponse
254259
err = json.Unmarshal(bodyBytes, &fastmailResponse)
255260
if err != nil {
256-
return nil, err
261+
return nil, fmt.Errorf("failed to parse response: %w", err)
257262
}
258263

259-
// the following manual unmarshaling code is due to the jmap response array
260-
// containing both strings and maps which does not elegantly map to nested
261-
// Go structs
262-
responsesLength := len(fastmailResponse.MethodResponses)
263-
if responsesLength < 1 {
264-
return nil, fmt.Errorf("invalid responses length: %v", responsesLength)
265-
}
266-
response := fastmailResponse.MethodResponses[0]
267-
responseLength := len(response)
268-
if responseLength < 2 {
269-
return nil, fmt.Errorf("invalid response length: %v", responseLength)
270-
}
271-
272-
responseMap, ok := response[1].(map[string]any)
273-
if !ok {
274-
return nil, fmt.Errorf("response was not a map: %v", response[1])
264+
if len(fastmailResponse.MethodResponses) < 1 {
265+
return nil, fmt.Errorf("empty method responses")
275266
}
276267

277-
createdAny, ok := responseMap[_jmapCreatedKey]
278-
if !ok {
279-
return nil, fmt.Errorf("%s key not found in response map: %v", _jmapCreatedKey, responseMap)
280-
}
281-
282-
created, ok := createdAny.(map[string]any)
283-
if !ok {
284-
return nil, fmt.Errorf("value for %s was not a map: %v", _jmapCreatedKey, createdAny)
268+
// Parse the heterogeneous array [method_name, response_object, call_id]
269+
var methodResponse []jsontext.Value
270+
err = json.Unmarshal(fastmailResponse.MethodResponses[0], &methodResponse)
271+
if err != nil {
272+
return nil, fmt.Errorf("failed to parse method response array: %w", err)
285273
}
286274

287-
fastmaskAny, ok := created[_fastmaskRequestId]
288-
if !ok {
289-
return nil, fmt.Errorf("no %s response in payload: %v", _fastmaskRequestId, created)
275+
if len(methodResponse) < 2 {
276+
return nil, fmt.Errorf("invalid method response length: %d", len(methodResponse))
290277
}
291278

292-
fastmaskMap, ok := fastmaskAny.(map[string]any)
293-
if !ok {
294-
return nil, fmt.Errorf("%s response was not a map: %v", _fastmaskRequestId, fastmaskAny)
279+
// Now unmarshal just the response object (index 1)
280+
var setResponse MaskedEmailSetResponse
281+
err = json.Unmarshal(methodResponse[1], &setResponse)
282+
if err != nil {
283+
return nil, fmt.Errorf("failed to parse set response: %w", err)
295284
}
296285

297-
emailAny, ok := fastmaskMap[_jmapEmailKey]
298-
if !ok {
299-
return nil, fmt.Errorf("no %s in payload: %v", _jmapEmailKey, fastmaskMap)
286+
maskedEmail, exists := setResponse.Created[_fastmaskRequestId]
287+
if !exists {
288+
return nil, fmt.Errorf("no fastmask response in created map")
300289
}
301290

302-
email, ok := emailAny.(string)
303-
if !ok {
304-
return nil, fmt.Errorf("%s was not a string: %v", _jmapEmailKey, emailAny)
291+
if maskedEmail.Email == "" {
292+
return nil, fmt.Errorf("email was empty in response")
305293
}
306294

307295
return &FastmaskResponse{
308296
Prefix: prefix,
309297
Domain: domain,
310-
Email: email,
298+
Email: maskedEmail.Email,
311299
}, nil
312300
}
313301

0 commit comments

Comments
 (0)