Source file src/encoding/json/internal/jsontest/testdata.go

     1  // Copyright 2020 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build goexperiment.jsonv2
     6  
     7  // Package jsontest contains functionality to assist in testing JSON.
     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  // Embed the testdata directory as a fs.FS because this package is imported
    25  // by other packages such that the location of testdata may change relative
    26  // to the working directory of the test itself.
    27  //
    28  // Various tools assume that testdata directories are unnecessary if you don't
    29  // need to run tests. This includes cmd/internal/bootstrap_test, which runs go
    30  // install std on a GOROOT excluding testdata directories. Since this is an
    31  // importable package rather than a test, to avoid breaking that case we must
    32  // not actually name the directory testdata.
    33  //
    34  //go:embed _embed/*.json.zst
    35  var testdataFS embed.FS
    36  
    37  type Entry struct {
    38  	Name string
    39  	Data func() []byte
    40  	New  func() any // nil if there is no concrete type for this
    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  // Data is a list of JSON testdata.
    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  		// Convert snake_case file name to CamelCase.
    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  		// Lazily read and decompress the test data.
    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  		// Check whether there is a concrete type for this data.
    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  // rawValue is the raw encoded JSON value.
   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