Metadata.cpp 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*
  2. * Copyright (c) 2023, kleines Filmröllchen <filmroellchen@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "Metadata.h"
  7. #include <AK/Assertions.h>
  8. #include <LibCore/Version.h>
  9. namespace Audio {
  10. bool Person::is_artist() const
  11. {
  12. return role == Person::Role::Artist
  13. || role == Person::Role::Composer
  14. || role == Person::Role::Conductor
  15. || role == Person::Role::Lyricist
  16. || role == Person::Role::Performer;
  17. }
  18. Optional<StringView> Person::name_for_role() const
  19. {
  20. switch (role) {
  21. case Role::Artist:
  22. case Role::Performer:
  23. return {};
  24. case Role::Lyricist:
  25. return "Lyricist"sv;
  26. case Role::Conductor:
  27. return "Conductor"sv;
  28. case Role::Publisher:
  29. return "Publisher"sv;
  30. case Role::Engineer:
  31. return "Engineer"sv;
  32. case Role::Composer:
  33. return "Composer"sv;
  34. }
  35. VERIFY_NOT_REACHED();
  36. }
  37. void Metadata::replace_encoder_with_serenity()
  38. {
  39. auto version_or_error = Core::Version::read_long_version_string();
  40. // Unset the encoder field in this case; we definitely want to replace the existing encoder field.
  41. if (version_or_error.is_error())
  42. encoder = {};
  43. auto encoder_string = String::formatted("SerenityOS LibAudio {}", version_or_error.release_value());
  44. if (encoder_string.is_error())
  45. encoder = {};
  46. encoder = encoder_string.release_value();
  47. }
  48. Optional<String> Metadata::first_artist() const
  49. {
  50. auto artist = people.find_if([](auto const& person) { return person.is_artist(); });
  51. if (artist.is_end())
  52. return {};
  53. return artist->name;
  54. }
  55. ErrorOr<Optional<String>> Metadata::all_artists(StringView concatenate_with) const
  56. {
  57. // FIXME: This entire function could be similar to TRY(TRY(people.filter(...).try_map(...)).join(concatenate_with)) if these functional iterator transformers existed :^)
  58. Vector<String> artist_texts;
  59. TRY(artist_texts.try_ensure_capacity(people.size()));
  60. for (auto const& person : people) {
  61. if (!person.is_artist())
  62. continue;
  63. if (auto role_name = person.name_for_role(); role_name.has_value())
  64. artist_texts.unchecked_append(TRY(String::formatted("{} ({})", person.name, role_name.release_value())));
  65. else
  66. artist_texts.unchecked_append(person.name);
  67. }
  68. if (artist_texts.is_empty())
  69. return Optional<String> {};
  70. return String::join(concatenate_with, artist_texts);
  71. }
  72. ErrorOr<void> Metadata::add_miscellaneous(String const& field, String value)
  73. {
  74. // FIXME: Since try_ensure does not return a reference to the contained value, we have to retrieve it separately.
  75. // This is a try_ensure bug that should be fixed.
  76. (void)TRY(miscellaneous.try_ensure(field, []() { return Vector<String> {}; }));
  77. auto& values_for_field = miscellaneous.get(field).release_value();
  78. return values_for_field.try_append(move(value));
  79. }
  80. ErrorOr<void> Metadata::add_person(Person::Role role, String name)
  81. {
  82. return people.try_append(Person { role, move(name) });
  83. }
  84. }