fork of indigo with slightly nicer lexgen
at main 2.0 kB view raw
1package client 2 3import ( 4 "bytes" 5 "context" 6 "encoding/json" 7 "fmt" 8 "io" 9 10 "github.com/bluesky-social/indigo/atproto/syntax" 11) 12 13// Implements the [github.com/bluesky-social/indigo/lex/util.LexClient] interface, for use with code-generated API helpers. 14func (c *APIClient) LexDo(ctx context.Context, method string, inputEncoding string, endpoint string, params map[string]any, bodyData any, out any) error { 15 // some of the code here is copied from indigo:xrpc/xrpc.go 16 17 nsid, err := syntax.ParseNSID(endpoint) 18 if err != nil { 19 return err 20 } 21 22 var body io.Reader 23 if bodyData != nil { 24 if rr, ok := bodyData.(io.Reader); ok { 25 body = rr 26 } else { 27 b, err := json.Marshal(bodyData) 28 if err != nil { 29 return err 30 } 31 32 body = bytes.NewReader(b) 33 if inputEncoding == "" { 34 inputEncoding = "application/json" 35 } 36 } 37 } 38 39 req := NewAPIRequest(method, nsid, body) 40 41 if inputEncoding != "" { 42 req.Headers.Set("Content-Type", inputEncoding) 43 } 44 45 if params != nil { 46 qp, err := ParseParams(params) 47 if err != nil { 48 return err 49 } 50 req.QueryParams = qp 51 } 52 53 resp, err := c.Do(ctx, req) 54 if err != nil { 55 return err 56 } 57 defer resp.Body.Close() 58 59 if !(resp.StatusCode >= 200 && resp.StatusCode < 300) { 60 var eb ErrorBody 61 if err := json.NewDecoder(resp.Body).Decode(&eb); err != nil { 62 return &APIError{StatusCode: resp.StatusCode} 63 } 64 return eb.APIError(resp.StatusCode) 65 } 66 67 if out == nil { 68 // drain body before returning 69 io.ReadAll(resp.Body) 70 return nil 71 } 72 73 if buf, ok := out.(*bytes.Buffer); ok { 74 if resp.ContentLength < 0 { 75 _, err := io.Copy(buf, resp.Body) 76 if err != nil { 77 return fmt.Errorf("reading response body: %w", err) 78 } 79 } else { 80 n, err := io.CopyN(buf, resp.Body, resp.ContentLength) 81 if err != nil { 82 return fmt.Errorf("reading length delimited response body (%d < %d): %w", n, resp.ContentLength, err) 83 } 84 } 85 } else { 86 if err := json.NewDecoder(resp.Body).Decode(out); err != nil { 87 return fmt.Errorf("failed decoding JSON response body: %w", err) 88 } 89 } 90 91 return nil 92}