| // Copyright 2024 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "google_apis/youtube_music/youtube_music_api_response_types.h" |
| |
| #include <string> |
| |
| #include "base/json/json_value_converter.h" |
| #include "base/strings/stringprintf.h" |
| |
| namespace google_apis::youtube_music { |
| namespace { |
| |
| using ::base::JSONValueConverter; |
| |
| constexpr char kApiResponseNameKey[] = "name"; |
| constexpr char kApiResponseTitleKey[] = "title"; |
| constexpr char kApiResponseMusicRecommendationsKey[] = "musicRecommendations"; |
| constexpr char kApiResponseMusicSectionKey[] = "musicSection"; |
| constexpr char kApiResponseWidthKey[] = "widthPixels"; |
| constexpr char kApiResponseHeightKey[] = "heightPixels"; |
| constexpr char kApiResponseUriKey[] = "uri"; |
| constexpr char kApiResponsePlaybackReportingTokenKey[] = |
| "playbackReportingToken"; |
| constexpr char kApiResponseDescriptionKey[] = "description"; |
| constexpr char kApiResponseItemCountKey[] = "itemCount"; |
| constexpr char kApiResponseImagesKey[] = "images"; |
| constexpr char kApiResponseArtistKey[] = "artist"; |
| constexpr char kApiResponseArtistReferencesKey[] = "artistReferences"; |
| constexpr char kApiResponseOwnerKey[] = "owner"; |
| constexpr char kApiResponsePlaylistKey[] = "playlist"; |
| constexpr char kApiResponseContextKey[] = "context"; |
| constexpr char kApiResponseSizeKey[] = "size"; |
| constexpr char kApiResponseQueueKey[] = "queue"; |
| constexpr char kApiResponseDurationKey[] = "duration"; |
| constexpr char kApiResponseExplicitTypeKey[] = "explicitType"; |
| constexpr char kApiResponseTrackKey[] = "track"; |
| constexpr char kApiResponseStreamsKey[] = "streams"; |
| constexpr char kApiResponseItemKey[] = "item"; |
| constexpr char kApiResponseManifestKey[] = "manifest"; |
| |
| bool ConvertToGurl(std::string_view input, GURL* output) { |
| *output = GURL(input); |
| return true; |
| } |
| |
| } // namespace |
| |
| Image::Image() = default; |
| Image::~Image() = default; |
| |
| // static |
| void Image::RegisterJSONConverter(JSONValueConverter<Image>* converter) { |
| converter->RegisterIntField(kApiResponseWidthKey, &Image::width_); |
| converter->RegisterIntField(kApiResponseHeightKey, &Image::height_); |
| converter->RegisterCustomField<GURL>(kApiResponseUriKey, &Image::url_, |
| &ConvertToGurl); |
| } |
| |
| std::string Image::ToString() const { |
| return base::StringPrintf("Image(width=%d, height=%d, url=\"%s\")", width_, |
| height_, url_.spec().c_str()); |
| } |
| |
| Owner::Owner() = default; |
| Owner::~Owner() = default; |
| |
| // static |
| void Owner::RegisterJSONConverter(JSONValueConverter<Owner>* converter) { |
| converter->RegisterStringField(kApiResponseTitleKey, &Owner::title_); |
| } |
| |
| std::string Owner::ToString() const { |
| return base::StringPrintf("Owner(title=\"%s\"", title_.c_str()); |
| } |
| |
| Playlist::Playlist() = default; |
| Playlist::~Playlist() = default; |
| |
| // static |
| void Playlist::RegisterJSONConverter(JSONValueConverter<Playlist>* converter) { |
| converter->RegisterStringField(kApiResponseNameKey, &Playlist::name_); |
| converter->RegisterStringField(kApiResponseTitleKey, &Playlist::title_); |
| converter->RegisterStringField(kApiResponseDescriptionKey, |
| &Playlist::description_); |
| converter->RegisterIntField(kApiResponseItemCountKey, &Playlist::item_count_); |
| converter->RegisterRepeatedMessage<Image>(kApiResponseImagesKey, |
| &Playlist::images_); |
| converter->RegisterNestedField(kApiResponseOwnerKey, &Playlist::owner_); |
| } |
| |
| // static |
| std::unique_ptr<Playlist> Playlist::CreateFrom(const base::Value& value) { |
| auto playlist = std::make_unique<Playlist>(); |
| JSONValueConverter<Playlist> converter; |
| if (!converter.Convert(value, playlist.get())) { |
| DVLOG(1) << "Unable to construct `Playlist` from parsed json."; |
| return nullptr; |
| } |
| return playlist; |
| } |
| |
| std::string Playlist::ToString() const { |
| std::string s; |
| for (size_t i = 0; i < images_.size(); i++) { |
| s += (i ? ", " : "") + images_[i]->ToString(); |
| } |
| return base::StringPrintf( |
| "Playlist(name=\"%s\", title=\"%s\", description=\"%s\", item_count=%d, " |
| "images=[%s], owner=%s)", |
| name_.c_str(), title_.c_str(), description_.c_str(), item_count_, |
| s.c_str(), owner_.ToString().c_str()); |
| } |
| |
| MusicRecommendation::MusicRecommendation() = default; |
| MusicRecommendation::~MusicRecommendation() = default; |
| |
| // static |
| void MusicRecommendation::RegisterJSONConverter( |
| JSONValueConverter<MusicRecommendation>* converter) { |
| converter->RegisterNestedField(kApiResponsePlaylistKey, |
| &MusicRecommendation::playlist_); |
| } |
| |
| std::string MusicRecommendation::ToString() const { |
| return base::StringPrintf("MusicRecommendation(playlist=%s)", |
| playlist_.ToString().c_str()); |
| } |
| |
| MusicSection::MusicSection() = default; |
| MusicSection::~MusicSection() = default; |
| |
| // static |
| void MusicSection::RegisterJSONConverter( |
| JSONValueConverter<MusicSection>* converter) { |
| converter->RegisterStringField(kApiResponseNameKey, &MusicSection::name_); |
| converter->RegisterStringField(kApiResponseTitleKey, &MusicSection::title_); |
| converter->RegisterRepeatedMessage<MusicRecommendation>( |
| kApiResponseMusicRecommendationsKey, |
| &MusicSection::music_recommendations_); |
| } |
| |
| // static |
| std::unique_ptr<MusicSection> MusicSection::CreateFrom( |
| const base::Value& value) { |
| auto music_section = std::make_unique<MusicSection>(); |
| JSONValueConverter<MusicSection> converter; |
| if (!converter.Convert(value, music_section.get())) { |
| DVLOG(1) << "Unable to construct `MusicSection` from parsed json."; |
| return nullptr; |
| } |
| return music_section; |
| } |
| |
| std::string MusicSection::ToString() const { |
| std::string s; |
| for (size_t i = 0; i < music_recommendations_.size(); i++) { |
| s += (i ? ", " : "") + music_recommendations_[i]->ToString(); |
| } |
| return base::StringPrintf( |
| "MusicSection(name=\"%s\", title=\"%s\", " |
| "music_recommendations=[%s])", |
| name_.c_str(), title_.c_str(), s.c_str()); |
| } |
| |
| TopLevelMusicRecommendation::TopLevelMusicRecommendation() = default; |
| TopLevelMusicRecommendation::~TopLevelMusicRecommendation() = default; |
| |
| // static |
| void TopLevelMusicRecommendation::RegisterJSONConverter( |
| JSONValueConverter<TopLevelMusicRecommendation>* converter) { |
| converter->RegisterNestedField(kApiResponseMusicSectionKey, |
| &TopLevelMusicRecommendation::music_section_); |
| } |
| |
| // static |
| std::unique_ptr<TopLevelMusicRecommendation> |
| TopLevelMusicRecommendation::CreateFrom(const base::Value& value) { |
| auto top_level_music_recommendation = |
| std::make_unique<TopLevelMusicRecommendation>(); |
| JSONValueConverter<TopLevelMusicRecommendation> converter; |
| if (!converter.Convert(value, top_level_music_recommendation.get())) { |
| DVLOG(1) << "Unable to construct `TopLevelMusicRecommendation` from parsed " |
| "json."; |
| return nullptr; |
| } |
| return top_level_music_recommendation; |
| } |
| |
| std::string TopLevelMusicRecommendation::ToString() const { |
| return base::StringPrintf("TopLevelMusicRecommendation(music_section=%s)", |
| music_section_.ToString().c_str()); |
| } |
| |
| TopLevelMusicRecommendations::TopLevelMusicRecommendations() = default; |
| TopLevelMusicRecommendations::~TopLevelMusicRecommendations() = default; |
| |
| // static |
| void TopLevelMusicRecommendations::RegisterJSONConverter( |
| JSONValueConverter<TopLevelMusicRecommendations>* converter) { |
| converter->RegisterRepeatedMessage<TopLevelMusicRecommendation>( |
| kApiResponseMusicRecommendationsKey, |
| &TopLevelMusicRecommendations::top_level_music_recommendations_); |
| } |
| |
| // static |
| std::unique_ptr<TopLevelMusicRecommendations> |
| TopLevelMusicRecommendations::CreateFrom(const base::Value& value) { |
| auto top_level_music_recommendations = |
| std::make_unique<TopLevelMusicRecommendations>(); |
| JSONValueConverter<TopLevelMusicRecommendations> converter; |
| if (!converter.Convert(value, top_level_music_recommendations.get())) { |
| DVLOG(1) << "Unable to construct `TopLevelMusicRecommendations` from " |
| "parsed json."; |
| return nullptr; |
| } |
| return top_level_music_recommendations; |
| } |
| |
| std::string TopLevelMusicRecommendations::ToString() const { |
| std::string s; |
| for (size_t i = 0; i < top_level_music_recommendations_.size(); i++) { |
| s += (i ? ", " : "") + top_level_music_recommendations_[i]->ToString(); |
| } |
| return base::StringPrintf( |
| "TopLevelMusicRecommendations(top_level_music_recommendations=[%s])", |
| s.c_str()); |
| } |
| |
| ArtistReference::ArtistReference() = default; |
| ArtistReference::~ArtistReference() = default; |
| |
| // static |
| void ArtistReference::RegisterJSONConverter( |
| JSONValueConverter<ArtistReference>* converter) { |
| converter->RegisterStringField(kApiResponseArtistKey, |
| &ArtistReference::artist_); |
| converter->RegisterStringField(kApiResponseTitleKey, |
| &ArtistReference::title_); |
| } |
| |
| // static |
| std::unique_ptr<ArtistReference> ArtistReference::CreateFrom( |
| const base::Value& value) { |
| auto artist_reference = std::make_unique<ArtistReference>(); |
| JSONValueConverter<ArtistReference> converter; |
| if (!converter.Convert(value, artist_reference.get())) { |
| DVLOG(1) << "Unable to construct `ArtistReference` from parsed json."; |
| return nullptr; |
| } |
| return artist_reference; |
| } |
| |
| std::string ArtistReference::ToString() const { |
| return base::StringPrintf("ArtistReference(artist=\"%s\", title=\"%s\"", |
| artist_.c_str(), title_.c_str()); |
| } |
| |
| Track::Track() = default; |
| Track::~Track() = default; |
| |
| // static |
| void Track::RegisterJSONConverter(JSONValueConverter<Track>* converter) { |
| converter->RegisterStringField(kApiResponseNameKey, &Track::name_); |
| converter->RegisterStringField(kApiResponseTitleKey, &Track::title_); |
| converter->RegisterStringField(kApiResponseDurationKey, &Track::duration_); |
| converter->RegisterStringField(kApiResponseExplicitTypeKey, |
| &Track::explicit_type_); |
| converter->RegisterRepeatedMessage<Image>(kApiResponseImagesKey, |
| &Track::images_); |
| converter->RegisterRepeatedMessage<ArtistReference>( |
| kApiResponseArtistReferencesKey, &Track::artist_references_); |
| } |
| |
| // static |
| std::unique_ptr<Track> Track::CreateFrom(const base::Value& value) { |
| auto track = std::make_unique<Track>(); |
| JSONValueConverter<Track> converter; |
| if (!converter.Convert(value, track.get())) { |
| DVLOG(1) << "Unable to construct `Track` from parsed json."; |
| return nullptr; |
| } |
| return track; |
| } |
| |
| std::string Track::ToString() const { |
| std::string s; |
| for (size_t i = 0; i < images_.size(); i++) { |
| s += (i ? ", " : "") + images_[i]->ToString(); |
| } |
| return base::StringPrintf( |
| "Track(name=\"%s\", title=\"%s\", duration=\"%s\", explicit_type_=%s, " |
| "images=[%s])", |
| name_.c_str(), title_.c_str(), duration_.c_str(), explicit_type_.c_str(), |
| s.c_str()); |
| } |
| |
| QueueItem::QueueItem() = default; |
| QueueItem::~QueueItem() = default; |
| |
| // static |
| void QueueItem::RegisterJSONConverter( |
| JSONValueConverter<QueueItem>* converter) { |
| converter->RegisterNestedField(kApiResponseTrackKey, &QueueItem::track_); |
| } |
| |
| // static |
| std::unique_ptr<QueueItem> QueueItem::CreateFrom(const base::Value& value) { |
| auto queue_item = std::make_unique<QueueItem>(); |
| JSONValueConverter<QueueItem> converter; |
| if (!converter.Convert(value, queue_item.get())) { |
| DVLOG(1) << "Unable to construct `QueueItem` from parsed json."; |
| return nullptr; |
| } |
| return queue_item; |
| } |
| |
| std::string QueueItem::ToString() const { |
| return base::StringPrintf("QueueItem(track=%s)", track_.ToString().c_str()); |
| } |
| |
| Stream::Stream() = default; |
| Stream::~Stream() = default; |
| |
| // static |
| void Stream::RegisterJSONConverter(JSONValueConverter<Stream>* converter) { |
| converter->RegisterCustomField<GURL>(kApiResponseUriKey, &Stream::url_, |
| &ConvertToGurl); |
| converter->RegisterStringField(kApiResponsePlaybackReportingTokenKey, |
| &Stream::playback_reporting_token_); |
| } |
| |
| // static |
| std::unique_ptr<Stream> Stream::CreateFrom(const base::Value& value) { |
| auto stream = std::make_unique<Stream>(); |
| JSONValueConverter<Stream> converter; |
| if (!converter.Convert(value, stream.get())) { |
| DVLOG(1) << "Unable to construct `Stream` from parsed json."; |
| return nullptr; |
| } |
| return stream; |
| } |
| |
| std::string Stream::ToString() const { |
| return base::StringPrintf( |
| "Stream(url=\"%s\", playback_reporting_token=\"%s\")", |
| url_.spec().c_str(), playback_reporting_token_.c_str()); |
| } |
| |
| PlaybackManifest::PlaybackManifest() = default; |
| PlaybackManifest::~PlaybackManifest() = default; |
| |
| // static |
| void PlaybackManifest::RegisterJSONConverter( |
| JSONValueConverter<PlaybackManifest>* converter) { |
| converter->RegisterRepeatedMessage<Stream>(kApiResponseStreamsKey, |
| &PlaybackManifest::streams_); |
| } |
| |
| // static |
| std::unique_ptr<PlaybackManifest> PlaybackManifest::CreateFrom( |
| const base::Value& value) { |
| auto playback_manifest = std::make_unique<PlaybackManifest>(); |
| JSONValueConverter<PlaybackManifest> converter; |
| if (!converter.Convert(value, playback_manifest.get())) { |
| DVLOG(1) << "Unable to construct `PlaybackManifest` from parsed json."; |
| return nullptr; |
| } |
| return playback_manifest; |
| } |
| |
| std::string PlaybackManifest::ToString() const { |
| std::string s; |
| for (size_t i = 0; i < streams_.size(); i++) { |
| s += (i ? ", " : "") + streams_[i]->ToString(); |
| } |
| return base::StringPrintf("PlaybackManifest(streams=[%s])", s.c_str()); |
| } |
| |
| PlaybackContext::PlaybackContext() = default; |
| PlaybackContext::~PlaybackContext() = default; |
| |
| // static |
| void PlaybackContext::RegisterJSONConverter( |
| JSONValueConverter<PlaybackContext>* converter) { |
| converter->RegisterNestedField(kApiResponseItemKey, |
| &PlaybackContext::queue_item_); |
| converter->RegisterNestedField(kApiResponseManifestKey, |
| &PlaybackContext::playback_manifest_); |
| } |
| |
| // static |
| std::unique_ptr<PlaybackContext> PlaybackContext::CreateFrom( |
| const base::Value& value) { |
| auto playback_context = std::make_unique<PlaybackContext>(); |
| JSONValueConverter<PlaybackContext> converter; |
| if (!converter.Convert(value, playback_context.get())) { |
| DVLOG(1) << "Unable to construct `PlaybackManifest` from parsed json."; |
| return nullptr; |
| } |
| return playback_context; |
| } |
| |
| std::string PlaybackContext::ToString() const { |
| return base::StringPrintf( |
| "PlaybackContext(queue_item=%s, playback_manifest=%s)", |
| queue_item_.ToString().c_str(), playback_manifest_.ToString().c_str()); |
| } |
| |
| Queue::Queue() = default; |
| Queue::~Queue() = default; |
| |
| // static |
| void Queue::RegisterJSONConverter(JSONValueConverter<Queue>* converter) { |
| converter->RegisterStringField(kApiResponseNameKey, &Queue::name_); |
| converter->RegisterIntField(kApiResponseSizeKey, &Queue::size_); |
| converter->RegisterNestedField(kApiResponseContextKey, |
| &Queue::playback_context_); |
| } |
| |
| // static |
| std::unique_ptr<Queue> Queue::CreateFrom(const base::Value& value) { |
| auto queue = std::make_unique<Queue>(); |
| JSONValueConverter<Queue> converter; |
| if (!converter.Convert(value, queue.get())) { |
| DVLOG(1) << "Unable to construct `Queue` from parsed json."; |
| return nullptr; |
| } |
| return queue; |
| } |
| |
| std::string Queue::ToString() const { |
| return base::StringPrintf("Queue(name=\"%s\", size=%d, playback_context=%s)", |
| name_.c_str(), size_, |
| playback_context_.ToString().c_str()); |
| } |
| |
| QueueContainer::QueueContainer() = default; |
| QueueContainer::~QueueContainer() = default; |
| |
| // static |
| void QueueContainer::RegisterJSONConverter( |
| JSONValueConverter<QueueContainer>* converter) { |
| converter->RegisterNestedField(kApiResponseQueueKey, &QueueContainer::queue_); |
| } |
| |
| // static |
| std::unique_ptr<QueueContainer> QueueContainer::CreateFrom( |
| const base::Value& value) { |
| auto queue_container = std::make_unique<QueueContainer>(); |
| JSONValueConverter<QueueContainer> converter; |
| if (!converter.Convert(value, queue_container.get())) { |
| DVLOG(1) << "Unable to construct `QueueContainer` from parsed json."; |
| return nullptr; |
| } |
| return queue_container; |
| } |
| |
| std::string QueueContainer::ToString() const { |
| return base::StringPrintf("QueueContainer(queue=%s)", |
| queue_.ToString().c_str()); |
| } |
| |
| ReportPlaybackResult::ReportPlaybackResult() = default; |
| ReportPlaybackResult::~ReportPlaybackResult() = default; |
| |
| // static |
| void ReportPlaybackResult::RegisterJSONConverter( |
| JSONValueConverter<ReportPlaybackResult>* converter) { |
| converter->RegisterStringField( |
| kApiResponsePlaybackReportingTokenKey, |
| &ReportPlaybackResult::playback_reporting_token_); |
| } |
| |
| // static |
| std::unique_ptr<ReportPlaybackResult> ReportPlaybackResult::CreateFrom( |
| const base::Value& value) { |
| auto report_playback_result = std::make_unique<ReportPlaybackResult>(); |
| JSONValueConverter<ReportPlaybackResult> converter; |
| if (!converter.Convert(value, report_playback_result.get())) { |
| DVLOG(1) << "Unable to construct `ReportPlaybackResult` from parsed json."; |
| return nullptr; |
| } |
| return report_playback_result; |
| } |
| |
| std::string ReportPlaybackResult::ToString() const { |
| return base::StringPrintf("ReportPlaybackResult(playback_reporting_token=%s)", |
| playback_reporting_token_.c_str()); |
| } |
| |
| } // namespace google_apis::youtube_music |