1
2
3
4
5
6
7
8 package jsontest
9
10 import (
11 "bytes"
12 "embed"
13 "errors"
14 "internal/zstd"
15 "io"
16 "io/fs"
17 "path"
18 "slices"
19 "strings"
20 "sync"
21 "time"
22 )
23
24
25
26
27
28
29
30
31
32
33
34
35 var testdataFS embed.FS
36
37 type Entry struct {
38 Name string
39 Data func() []byte
40 New func() any
41 }
42
43 func mustGet[T any](v T, err error) T {
44 if err != nil {
45 panic(err)
46 }
47 return v
48 }
49
50
51 var Data = func() (entries []Entry) {
52 fis := mustGet(fs.ReadDir(testdataFS, "_embed"))
53 slices.SortFunc(fis, func(x, y fs.DirEntry) int { return strings.Compare(x.Name(), y.Name()) })
54 for _, fi := range fis {
55 var entry Entry
56
57
58 words := strings.Split(strings.TrimSuffix(fi.Name(), ".json.zst"), "_")
59 for i := range words {
60 words[i] = strings.Title(words[i])
61 }
62 entry.Name = strings.Join(words, "")
63
64
65 entry.Data = sync.OnceValue(func() []byte {
66 filePath := path.Join("_embed", fi.Name())
67 b := mustGet(fs.ReadFile(testdataFS, filePath))
68 zr := zstd.NewReader(bytes.NewReader(b))
69 return mustGet(io.ReadAll(zr))
70 })
71
72
73 switch entry.Name {
74 case "CanadaGeometry":
75 entry.New = func() any { return new(canadaRoot) }
76 case "CitmCatalog":
77 entry.New = func() any { return new(citmRoot) }
78 case "GolangSource":
79 entry.New = func() any { return new(golangRoot) }
80 case "StringEscaped":
81 entry.New = func() any { return new(stringRoot) }
82 case "StringUnicode":
83 entry.New = func() any { return new(stringRoot) }
84 case "SyntheaFhir":
85 entry.New = func() any { return new(syntheaRoot) }
86 case "TwitterStatus":
87 entry.New = func() any { return new(twitterRoot) }
88 }
89
90 entries = append(entries, entry)
91 }
92 return entries
93 }()
94
95 type (
96 canadaRoot struct {
97 Type string `json:"type"`
98 Features []struct {
99 Type string `json:"type"`
100 Properties struct {
101 Name string `json:"name"`
102 } `json:"properties"`
103 Geometry struct {
104 Type string `json:"type"`
105 Coordinates [][][2]float64 `json:"coordinates"`
106 } `json:"geometry"`
107 } `json:"features"`
108 }
109 )
110
111 type (
112 citmRoot struct {
113 AreaNames map[int64]string `json:"areaNames"`
114 AudienceSubCategoryNames map[int64]string `json:"audienceSubCategoryNames"`
115 BlockNames map[int64]string `json:"blockNames"`
116 Events map[int64]struct {
117 Description string `json:"description"`
118 ID int `json:"id"`
119 Logo string `json:"logo"`
120 Name string `json:"name"`
121 SubTopicIds []int `json:"subTopicIds"`
122 SubjectCode any `json:"subjectCode"`
123 Subtitle any `json:"subtitle"`
124 TopicIds []int `json:"topicIds"`
125 } `json:"events"`
126 Performances []struct {
127 EventID int `json:"eventId"`
128 ID int `json:"id"`
129 Logo any `json:"logo"`
130 Name any `json:"name"`
131 Prices []struct {
132 Amount int `json:"amount"`
133 AudienceSubCategoryID int64 `json:"audienceSubCategoryId"`
134 SeatCategoryID int64 `json:"seatCategoryId"`
135 } `json:"prices"`
136 SeatCategories []struct {
137 Areas []struct {
138 AreaID int `json:"areaId"`
139 BlockIds []any `json:"blockIds"`
140 } `json:"areas"`
141 SeatCategoryID int `json:"seatCategoryId"`
142 } `json:"seatCategories"`
143 SeatMapImage any `json:"seatMapImage"`
144 Start int64 `json:"start"`
145 VenueCode string `json:"venueCode"`
146 } `json:"performances"`
147 SeatCategoryNames map[uint64]string `json:"seatCategoryNames"`
148 SubTopicNames map[uint64]string `json:"subTopicNames"`
149 SubjectNames map[uint64]string `json:"subjectNames"`
150 TopicNames map[uint64]string `json:"topicNames"`
151 TopicSubTopics map[uint64][]uint64 `json:"topicSubTopics"`
152 VenueNames map[string]string `json:"venueNames"`
153 }
154 )
155
156 type (
157 golangRoot struct {
158 Tree *golangNode `json:"tree"`
159 Username string `json:"username"`
160 }
161 golangNode struct {
162 Name string `json:"name"`
163 Kids []golangNode `json:"kids"`
164 CLWeight float64 `json:"cl_weight"`
165 Touches int `json:"touches"`
166 MinT uint64 `json:"min_t"`
167 MaxT uint64 `json:"max_t"`
168 MeanT uint64 `json:"mean_t"`
169 }
170 )
171
172 type (
173 stringRoot struct {
174 Arabic string `json:"Arabic"`
175 ArabicPresentationFormsA string `json:"Arabic Presentation Forms-A"`
176 ArabicPresentationFormsB string `json:"Arabic Presentation Forms-B"`
177 Armenian string `json:"Armenian"`
178 Arrows string `json:"Arrows"`
179 Bengali string `json:"Bengali"`
180 Bopomofo string `json:"Bopomofo"`
181 BoxDrawing string `json:"Box Drawing"`
182 CJKCompatibility string `json:"CJK Compatibility"`
183 CJKCompatibilityForms string `json:"CJK Compatibility Forms"`
184 CJKCompatibilityIdeographs string `json:"CJK Compatibility Ideographs"`
185 CJKSymbolsAndPunctuation string `json:"CJK Symbols and Punctuation"`
186 CJKUnifiedIdeographs string `json:"CJK Unified Ideographs"`
187 CJKUnifiedIdeographsExtensionA string `json:"CJK Unified Ideographs Extension A"`
188 CJKUnifiedIdeographsExtensionB string `json:"CJK Unified Ideographs Extension B"`
189 Cherokee string `json:"Cherokee"`
190 CurrencySymbols string `json:"Currency Symbols"`
191 Cyrillic string `json:"Cyrillic"`
192 CyrillicSupplementary string `json:"Cyrillic Supplementary"`
193 Devanagari string `json:"Devanagari"`
194 EnclosedAlphanumerics string `json:"Enclosed Alphanumerics"`
195 EnclosedCJKLettersAndMonths string `json:"Enclosed CJK Letters and Months"`
196 Ethiopic string `json:"Ethiopic"`
197 GeometricShapes string `json:"Geometric Shapes"`
198 Georgian string `json:"Georgian"`
199 GreekAndCoptic string `json:"Greek and Coptic"`
200 Gujarati string `json:"Gujarati"`
201 Gurmukhi string `json:"Gurmukhi"`
202 HangulCompatibilityJamo string `json:"Hangul Compatibility Jamo"`
203 HangulJamo string `json:"Hangul Jamo"`
204 HangulSyllables string `json:"Hangul Syllables"`
205 Hebrew string `json:"Hebrew"`
206 Hiragana string `json:"Hiragana"`
207 IPAExtentions string `json:"IPA Extentions"`
208 KangxiRadicals string `json:"Kangxi Radicals"`
209 Katakana string `json:"Katakana"`
210 Khmer string `json:"Khmer"`
211 KhmerSymbols string `json:"Khmer Symbols"`
212 Latin string `json:"Latin"`
213 LatinExtendedAdditional string `json:"Latin Extended Additional"`
214 Latin1Supplement string `json:"Latin-1 Supplement"`
215 LatinExtendedA string `json:"Latin-Extended A"`
216 LatinExtendedB string `json:"Latin-Extended B"`
217 LetterlikeSymbols string `json:"Letterlike Symbols"`
218 Malayalam string `json:"Malayalam"`
219 MathematicalAlphanumericSymbols string `json:"Mathematical Alphanumeric Symbols"`
220 MathematicalOperators string `json:"Mathematical Operators"`
221 MiscellaneousSymbols string `json:"Miscellaneous Symbols"`
222 Mongolian string `json:"Mongolian"`
223 NumberForms string `json:"Number Forms"`
224 Oriya string `json:"Oriya"`
225 PhoneticExtensions string `json:"Phonetic Extensions"`
226 SupplementalArrowsB string `json:"Supplemental Arrows-B"`
227 Syriac string `json:"Syriac"`
228 Tamil string `json:"Tamil"`
229 Thaana string `json:"Thaana"`
230 Thai string `json:"Thai"`
231 UnifiedCanadianAboriginalSyllabics string `json:"Unified Canadian Aboriginal Syllabics"`
232 YiRadicals string `json:"Yi Radicals"`
233 YiSyllables string `json:"Yi Syllables"`
234 }
235 )
236
237 type (
238 syntheaRoot struct {
239 Entry []struct {
240 FullURL string `json:"fullUrl"`
241 Request *struct {
242 Method string `json:"method"`
243 URL string `json:"url"`
244 } `json:"request"`
245 Resource *struct {
246 AbatementDateTime time.Time `json:"abatementDateTime"`
247 AchievementStatus syntheaCode `json:"achievementStatus"`
248 Active bool `json:"active"`
249 Activity []struct {
250 Detail *struct {
251 Code syntheaCode `json:"code"`
252 Location syntheaReference `json:"location"`
253 Status string `json:"status"`
254 } `json:"detail"`
255 } `json:"activity"`
256 Address []syntheaAddress `json:"address"`
257 Addresses []syntheaReference `json:"addresses"`
258 AuthoredOn time.Time `json:"authoredOn"`
259 BillablePeriod syntheaRange `json:"billablePeriod"`
260 BirthDate string `json:"birthDate"`
261 CareTeam []struct {
262 Provider syntheaReference `json:"provider"`
263 Reference string `json:"reference"`
264 Role syntheaCode `json:"role"`
265 Sequence int64 `json:"sequence"`
266 } `json:"careTeam"`
267 Category []syntheaCode `json:"category"`
268 Claim syntheaReference `json:"claim"`
269 Class syntheaCoding `json:"class"`
270 ClinicalStatus syntheaCode `json:"clinicalStatus"`
271 Code syntheaCode `json:"code"`
272 Communication []struct {
273 Language syntheaCode `json:"language"`
274 } `json:"communication"`
275 Component []struct {
276 Code syntheaCode `json:"code"`
277 ValueQuantity syntheaCoding `json:"valueQuantity"`
278 } `json:"component"`
279 Contained []struct {
280 Beneficiary syntheaReference `json:"beneficiary"`
281 ID string `json:"id"`
282 Intent string `json:"intent"`
283 Payor []syntheaReference `json:"payor"`
284 Performer []syntheaReference `json:"performer"`
285 Requester syntheaReference `json:"requester"`
286 ResourceType string `json:"resourceType"`
287 Status string `json:"status"`
288 Subject syntheaReference `json:"subject"`
289 Type syntheaCode `json:"type"`
290 } `json:"contained"`
291 Created time.Time `json:"created"`
292 DeceasedDateTime time.Time `json:"deceasedDateTime"`
293 Description syntheaCode `json:"description"`
294 Diagnosis []struct {
295 DiagnosisReference syntheaReference `json:"diagnosisReference"`
296 Sequence int64 `json:"sequence"`
297 Type []syntheaCode `json:"type"`
298 } `json:"diagnosis"`
299 DosageInstruction []struct {
300 AsNeededBoolean bool `json:"asNeededBoolean"`
301 DoseAndRate []struct {
302 DoseQuantity *struct {
303 Value float64 `json:"value"`
304 } `json:"doseQuantity"`
305 Type syntheaCode `json:"type"`
306 } `json:"doseAndRate"`
307 Sequence int64 `json:"sequence"`
308 Timing *struct {
309 Repeat *struct {
310 Frequency int64 `json:"frequency"`
311 Period float64 `json:"period"`
312 PeriodUnit string `json:"periodUnit"`
313 } `json:"repeat"`
314 } `json:"timing"`
315 } `json:"dosageInstruction"`
316 EffectiveDateTime time.Time `json:"effectiveDateTime"`
317 Encounter syntheaReference `json:"encounter"`
318 Extension []syntheaExtension `json:"extension"`
319 Gender string `json:"gender"`
320 Goal []syntheaReference `json:"goal"`
321 ID string `json:"id"`
322 Identifier []struct {
323 System string `json:"system"`
324 Type syntheaCode `json:"type"`
325 Use string `json:"use"`
326 Value string `json:"value"`
327 } `json:"identifier"`
328 Insurance []struct {
329 Coverage syntheaReference `json:"coverage"`
330 Focal bool `json:"focal"`
331 Sequence int64 `json:"sequence"`
332 } `json:"insurance"`
333 Insurer syntheaReference `json:"insurer"`
334 Intent string `json:"intent"`
335 Issued time.Time `json:"issued"`
336 Item []struct {
337 Adjudication []struct {
338 Amount syntheaCurrency `json:"amount"`
339 Category syntheaCode `json:"category"`
340 } `json:"adjudication"`
341 Category syntheaCode `json:"category"`
342 DiagnosisSequence []int64 `json:"diagnosisSequence"`
343 Encounter []syntheaReference `json:"encounter"`
344 InformationSequence []int64 `json:"informationSequence"`
345 LocationCodeableConcept syntheaCode `json:"locationCodeableConcept"`
346 Net syntheaCurrency `json:"net"`
347 ProcedureSequence []int64 `json:"procedureSequence"`
348 ProductOrService syntheaCode `json:"productOrService"`
349 Sequence int64 `json:"sequence"`
350 ServicedPeriod syntheaRange `json:"servicedPeriod"`
351 } `json:"item"`
352 LifecycleStatus string `json:"lifecycleStatus"`
353 ManagingOrganization []syntheaReference `json:"managingOrganization"`
354 MaritalStatus syntheaCode `json:"maritalStatus"`
355 MedicationCodeableConcept syntheaCode `json:"medicationCodeableConcept"`
356 MultipleBirthBoolean bool `json:"multipleBirthBoolean"`
357 Name rawValue `json:"name"`
358 NumberOfInstances int64 `json:"numberOfInstances"`
359 NumberOfSeries int64 `json:"numberOfSeries"`
360 OccurrenceDateTime time.Time `json:"occurrenceDateTime"`
361 OnsetDateTime time.Time `json:"onsetDateTime"`
362 Outcome string `json:"outcome"`
363 Participant []struct {
364 Individual syntheaReference `json:"individual"`
365 Member syntheaReference `json:"member"`
366 Role []syntheaCode `json:"role"`
367 } `json:"participant"`
368 Patient syntheaReference `json:"patient"`
369 Payment *struct {
370 Amount syntheaCurrency `json:"amount"`
371 } `json:"payment"`
372 PerformedPeriod syntheaRange `json:"performedPeriod"`
373 Period syntheaRange `json:"period"`
374 Prescription syntheaReference `json:"prescription"`
375 PrimarySource bool `json:"primarySource"`
376 Priority syntheaCode `json:"priority"`
377 Procedure []struct {
378 ProcedureReference syntheaReference `json:"procedureReference"`
379 Sequence int64 `json:"sequence"`
380 } `json:"procedure"`
381 Provider syntheaReference `json:"provider"`
382 ReasonCode []syntheaCode `json:"reasonCode"`
383 ReasonReference []syntheaReference `json:"reasonReference"`
384 RecordedDate time.Time `json:"recordedDate"`
385 Referral syntheaReference `json:"referral"`
386 Requester syntheaReference `json:"requester"`
387 ResourceType string `json:"resourceType"`
388 Result []syntheaReference `json:"result"`
389 Series []struct {
390 BodySite syntheaCoding `json:"bodySite"`
391 Instance []struct {
392 Number int64 `json:"number"`
393 SopClass syntheaCoding `json:"sopClass"`
394 Title string `json:"title"`
395 UID string `json:"uid"`
396 } `json:"instance"`
397 Modality syntheaCoding `json:"modality"`
398 Number int64 `json:"number"`
399 NumberOfInstances int64 `json:"numberOfInstances"`
400 Started string `json:"started"`
401 UID string `json:"uid"`
402 } `json:"series"`
403 ServiceProvider syntheaReference `json:"serviceProvider"`
404 Started time.Time `json:"started"`
405 Status string `json:"status"`
406 Subject syntheaReference `json:"subject"`
407 SupportingInfo []struct {
408 Category syntheaCode `json:"category"`
409 Sequence int64 `json:"sequence"`
410 ValueReference syntheaReference `json:"valueReference"`
411 } `json:"supportingInfo"`
412 Telecom []map[string]string `json:"telecom"`
413 Text map[string]string `json:"text"`
414 Total rawValue `json:"total"`
415 Type rawValue `json:"type"`
416 Use string `json:"use"`
417 VaccineCode syntheaCode `json:"vaccineCode"`
418 ValueCodeableConcept syntheaCode `json:"valueCodeableConcept"`
419 ValueQuantity syntheaCoding `json:"valueQuantity"`
420 VerificationStatus syntheaCode `json:"verificationStatus"`
421 } `json:"resource"`
422 } `json:"entry"`
423 ResourceType string `json:"resourceType"`
424 Type string `json:"type"`
425 }
426 syntheaCode struct {
427 Coding []syntheaCoding `json:"coding"`
428 Text string `json:"text"`
429 }
430 syntheaCoding struct {
431 Code string `json:"code"`
432 Display string `json:"display"`
433 System string `json:"system"`
434 Unit string `json:"unit"`
435 Value float64 `json:"value"`
436 }
437 syntheaReference struct {
438 Display string `json:"display"`
439 Reference string `json:"reference"`
440 }
441 syntheaAddress struct {
442 City string `json:"city"`
443 Country string `json:"country"`
444 Extension []syntheaExtension `json:"extension"`
445 Line []string `json:"line"`
446 PostalCode string `json:"postalCode"`
447 State string `json:"state"`
448 }
449 syntheaExtension struct {
450 URL string `json:"url"`
451 ValueAddress syntheaAddress `json:"valueAddress"`
452 ValueCode string `json:"valueCode"`
453 ValueDecimal float64 `json:"valueDecimal"`
454 ValueString string `json:"valueString"`
455 Extension []syntheaExtension `json:"extension"`
456 }
457 syntheaRange struct {
458 End time.Time `json:"end"`
459 Start time.Time `json:"start"`
460 }
461 syntheaCurrency struct {
462 Currency string `json:"currency"`
463 Value float64 `json:"value"`
464 }
465 )
466
467 type (
468 twitterRoot struct {
469 Statuses []twitterStatus `json:"statuses"`
470 SearchMetadata struct {
471 CompletedIn float64 `json:"completed_in"`
472 MaxID int64 `json:"max_id"`
473 MaxIDStr int64 `json:"max_id_str,string"`
474 NextResults string `json:"next_results"`
475 Query string `json:"query"`
476 RefreshURL string `json:"refresh_url"`
477 Count int `json:"count"`
478 SinceID int `json:"since_id"`
479 SinceIDStr int `json:"since_id_str,string"`
480 } `json:"search_metadata"`
481 }
482 twitterStatus struct {
483 Metadata struct {
484 ResultType string `json:"result_type"`
485 IsoLanguageCode string `json:"iso_language_code"`
486 } `json:"metadata"`
487 CreatedAt string `json:"created_at"`
488 ID int64 `json:"id"`
489 IDStr int64 `json:"id_str,string"`
490 Text string `json:"text"`
491 Source string `json:"source"`
492 Truncated bool `json:"truncated"`
493 InReplyToStatusID int64 `json:"in_reply_to_status_id"`
494 InReplyToStatusIDStr int64 `json:"in_reply_to_status_id_str,string"`
495 InReplyToUserID int64 `json:"in_reply_to_user_id"`
496 InReplyToUserIDStr int64 `json:"in_reply_to_user_id_str,string"`
497 InReplyToScreenName string `json:"in_reply_to_screen_name"`
498 User twitterUser `json:"user,omitempty"`
499 Geo any `json:"geo"`
500 Coordinates any `json:"coordinates"`
501 Place any `json:"place"`
502 Contributors any `json:"contributors"`
503 RetweetedStatus *twitterStatus `json:"retweeted_status"`
504 RetweetCount int `json:"retweet_count"`
505 FavoriteCount int `json:"favorite_count"`
506 Entities twitterEntities `json:"entities,omitempty"`
507 Favorited bool `json:"favorited"`
508 Retweeted bool `json:"retweeted"`
509 PossiblySensitive bool `json:"possibly_sensitive"`
510 Lang string `json:"lang"`
511 }
512 twitterUser struct {
513 ID int64 `json:"id"`
514 IDStr string `json:"id_str"`
515 Name string `json:"name"`
516 ScreenName string `json:"screen_name"`
517 Location string `json:"location"`
518 Description string `json:"description"`
519 URL any `json:"url"`
520 Entities twitterEntities `json:"entities"`
521 Protected bool `json:"protected"`
522 FollowersCount int `json:"followers_count"`
523 FriendsCount int `json:"friends_count"`
524 ListedCount int `json:"listed_count"`
525 CreatedAt string `json:"created_at"`
526 FavouritesCount int `json:"favourites_count"`
527 UtcOffset int `json:"utc_offset"`
528 TimeZone string `json:"time_zone"`
529 GeoEnabled bool `json:"geo_enabled"`
530 Verified bool `json:"verified"`
531 StatusesCount int `json:"statuses_count"`
532 Lang string `json:"lang"`
533 ContributorsEnabled bool `json:"contributors_enabled"`
534 IsTranslator bool `json:"is_translator"`
535 IsTranslationEnabled bool `json:"is_translation_enabled"`
536 ProfileBackgroundColor string `json:"profile_background_color"`
537 ProfileBackgroundImageURL string `json:"profile_background_image_url"`
538 ProfileBackgroundImageURLHTTPS string `json:"profile_background_image_url_https"`
539 ProfileBackgroundTile bool `json:"profile_background_tile"`
540 ProfileImageURL string `json:"profile_image_url"`
541 ProfileImageURLHTTPS string `json:"profile_image_url_https"`
542 ProfileBannerURL string `json:"profile_banner_url"`
543 ProfileLinkColor string `json:"profile_link_color"`
544 ProfileSidebarBorderColor string `json:"profile_sidebar_border_color"`
545 ProfileSidebarFillColor string `json:"profile_sidebar_fill_color"`
546 ProfileTextColor string `json:"profile_text_color"`
547 ProfileUseBackgroundImage bool `json:"profile_use_background_image"`
548 DefaultProfile bool `json:"default_profile"`
549 DefaultProfileImage bool `json:"default_profile_image"`
550 Following bool `json:"following"`
551 FollowRequestSent bool `json:"follow_request_sent"`
552 Notifications bool `json:"notifications"`
553 }
554 twitterEntities struct {
555 Hashtags []any `json:"hashtags"`
556 Symbols []any `json:"symbols"`
557 URL *twitterURL `json:"url"`
558 URLs []twitterURL `json:"urls"`
559 UserMentions []struct {
560 ScreenName string `json:"screen_name"`
561 Name string `json:"name"`
562 ID int64 `json:"id"`
563 IDStr int64 `json:"id_str,string"`
564 Indices []int `json:"indices"`
565 } `json:"user_mentions"`
566 Description struct {
567 URLs []twitterURL `json:"urls"`
568 } `json:"description"`
569 Media []struct {
570 ID int64 `json:"id"`
571 IDStr string `json:"id_str"`
572 Indices []int `json:"indices"`
573 MediaURL string `json:"media_url"`
574 MediaURLHTTPS string `json:"media_url_https"`
575 URL string `json:"url"`
576 DisplayURL string `json:"display_url"`
577 ExpandedURL string `json:"expanded_url"`
578 Type string `json:"type"`
579 Sizes map[string]struct {
580 W int `json:"w"`
581 H int `json:"h"`
582 Resize string `json:"resize"`
583 } `json:"sizes"`
584 SourceStatusID int64 `json:"source_status_id"`
585 SourceStatusIDStr int64 `json:"source_status_id_str,string"`
586 } `json:"media"`
587 }
588 twitterURL struct {
589 URL string `json:"url"`
590 URLs []twitterURL `json:"urls"`
591 ExpandedURL string `json:"expanded_url"`
592 DisplayURL string `json:"display_url"`
593 Indices []int `json:"indices"`
594 }
595 )
596
597
598 type rawValue []byte
599
600 func (v rawValue) MarshalJSON() ([]byte, error) {
601 if v == nil {
602 return []byte("null"), nil
603 }
604 return v, nil
605 }
606
607 func (v *rawValue) UnmarshalJSON(b []byte) error {
608 if v == nil {
609 return errors.New("jsontest.rawValue: UnmarshalJSON on nil pointer")
610 }
611 *v = append((*v)[:0], b...)
612 return nil
613 }
614
View as plain text