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

View as plain text