package judge import ( "encoding/json" "strconv" "strings" ) // FitAnswer is a with its shown bodies cut until its JSON is within limit bytes (MaxAnswerBytes for the node's key): // first the bodies' texts, from the last differing module back, keeping their paths; then the paths too. What is cut // is said in the answer's note. The verdict and every list of modules are never cut. func FitAnswer(a CandidateAnswer, limit int) CandidateAnswer { size := func() int { raw, err := json.Marshal(a) if err != nil { return 0 } return len(raw) } if size() <= limit { return a } a.Differs = append([]ModuleDiffers(nil), a.Differs...) for i := range a.Differs { a.Differs[i].Bodies = append([]ResourceBodies(nil), a.Differs[i].Bodies...) } cutTexts, cutPaths := false, false for i := len(a.Differs) - 1; i >= 0 && size() > limit; i-- { for j := range a.Differs[i].Bodies { a.Differs[i].Bodies[j].Composed, a.Differs[i].Bodies[j].Running = "", "" } cutTexts = true } for i := len(a.Differs) - 1; i >= 0 && size() > limit; i-- { for j := range a.Differs[i].Bodies { a.Differs[i].Bodies[j].Paths = nil } cutPaths = true } why := "the bodies shown were cut to keep the answer within " + strconv.Itoa(limit>>10) + " KiB" if cutPaths { why += ", their paths too" } if cutTexts { a.Note = strings.TrimPrefix(a.Note+"; ", "; ") + why } return a }