-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsubmit.go
101 lines (96 loc) · 2.55 KB
/
submit.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package arctic
import (
"context"
"encoding/json"
"errors"
"github.com/ArcticOJ/go-api-bindings/v0/types"
"github.com/ArcticOJ/go-api-bindings/v0/types/common"
"github.com/ArcticOJ/go-api-bindings/v0/types/submission"
"github.com/mitchellh/mapstructure"
"io"
)
func (c *Client) submitGeneric(ctx context.Context, problem, src, runtime string, streamed bool) (interface{}, error) {
var submissionId uint32
req := c.c.R().
SetPathParam("id", problem).
SetFormDataAnyType(map[string]interface{}{
"runtime": runtime,
"stream": streamed,
}).
EnableForceMultipart().
SetContext(ctx).
SetFile("code", src)
if streamed {
req.DisableAutoReadResponse()
} else {
req.SetSuccessResult(&submissionId)
}
res, e := req.Post("/problems/{id}/submit")
if e != nil {
return nil, e
}
if !res.IsSuccessState() {
var err common.Error
buf, _e := io.ReadAll(res.Body)
if _e != nil {
return nil, types.ErrReadBody
}
if json.Unmarshal(buf, &err) != nil {
return nil, errors.New(string(buf))
}
return nil, errors.New(err.Message)
}
if !streamed {
return submissionId, nil
} else {
resChan := make(chan interface{}, 1)
reader := json.NewDecoder(res.Body)
var _res submission.ResultResponse
go func() {
defer close(resChan)
for reader.More() {
if reader.Decode(&_res) != nil {
return
}
switch _res.Type {
case submission.ResponseTypeMetadata:
var meta submission.Metadata
if err := mapstructure.Decode(_res.Data, &meta); err != nil {
c.l.Fatal("error decoding metadata: %s", err)
}
resChan <- meta
case submission.ResponseTypeAck:
resChan <- nil
case submission.ResponseTypeCase:
var cr submission.CaseResult
if err := mapstructure.Decode(_res.Data, &cr); err != nil {
c.l.Fatal("error decoding case response: %s", err)
}
resChan <- cr
case submission.ResponseTypeFinal:
var fr submission.FinalResult
if err := mapstructure.Decode(_res.Data, &fr); err != nil {
c.l.Fatal("error decoding final response: %s", err)
}
resChan <- fr
return
}
}
}()
return resChan, nil
}
}
func (c *Client) SubmitStreamed(ctx context.Context, problem, src, runtime string) (chan interface{}, error) {
v, e := c.submitGeneric(ctx, problem, src, runtime, true)
if e != nil {
return nil, e
}
return v.(chan interface{}), nil
}
func (c *Client) Submit(ctx context.Context, problem, src, runtime string) (uint32, error) {
v, e := c.submitGeneric(ctx, problem, src, runtime, false)
if e != nil {
return 0, e
}
return v.(uint32), nil
}