diff --git a/album.go b/album.go index 9cd68f4..3d00026 100644 --- a/album.go +++ b/album.go @@ -62,40 +62,43 @@ func (a *Album) IsFull() bool { return a.Belong != "" && len(a.Songs) > 0 } // Copy makes a copy of [Album]. // For an [Album] where the IsFull method returns true, Copy zeroes fields to convert the copy into other variants. // For [Album] where IsFull returns false, any variant other than [AlbumVariantCurrent] is undefined. -func (a *Album) Copy(variant int) *Album { - if a == nil { - return nil +func (a *Album) Copy(v *Album, variant int) bool { + if v == nil || a == nil || v == a { + return false } - v := *a if variant == AlbumVariantCurrent { - return &v + *v = *a + return true } if !a.IsFull() { - return nil + return false } switch variant { case AlbumVariantFull: - break + *v = *a case AlbumVariantDetail: - a.Artists = nil + *v = *a + v.Artists = nil case AlbumVariantData: - a.Songs = nil + *v = *a + v.Songs = nil case AlbumVariantBase: - a.Intro = "" - a.Belong = "" - a.CoverDeURL = "" - a.Songs = nil + *v = *a + v.Intro = "" + v.Belong = "" + v.CoverDeURL = "" + v.Songs = nil default: - return nil + return false } - return a + return true } // Enrich populates the remaining fields of a non-full [Album]. diff --git a/album_test.go b/album_test.go index a1bb99d..68fee2d 100644 --- a/album_test.go +++ b/album_test.go @@ -33,24 +33,25 @@ func TestAlbum(t *testing.T) { name string a *Album variant int - want *Album + want Album + wantOk bool }{ - {"nil", nil, AlbumVariantDetail, nil}, - {"current", new(Album), AlbumVariantCurrent, new(Album)}, - {"full guard", new(Album), AlbumVariantDetail, nil}, + {"nil", nil, AlbumVariantDetail, Album{CID: -0xdeadbeef}, false}, + {"current", new(Album), AlbumVariantCurrent, Album{}, true}, + {"full guard", new(Album), AlbumVariantDetail, Album{CID: -0xdeadbeef}, false}, {"current full", &Album{ Belong: "\x00", Songs: []AlbumSong{{}}, - }, AlbumVariantCurrent, &Album{ + }, AlbumVariantCurrent, Album{ Belong: "\x00", Songs: []AlbumSong{{}}, - }}, + }, true}, {"oob", &Album{ Belong: "\x00", Songs: []AlbumSong{{}}, - }, 0xbad, nil}, + }, 0xbad, Album{CID: -0xdeadbeef}, false}, {"full", &Album{ CID: 1030, @@ -64,7 +65,7 @@ func TestAlbum(t *testing.T) { {CID: 125012, Name: "Speed of Light (Instrumental)", Artists: []string{"DJ Okawari"}}, }, Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, - }, AlbumVariantFull, &Album{ + }, AlbumVariantFull, Album{ CID: 1030, Name: "Speed of Light", Intro: "在无人告知方向的黑夜里,独自以光速探寻正确的道路。 \n无论看待世界是简单,亦或是复杂,大地和天空始终让开始与结束相连。 \n《Speed of Light》,通过乐调铺陈的驰放与内敛感,希望能为您呈现超脱于现实的惬意想象空间。 \n愿您掌心的小小地图一直指引着前路。像光一样前行,如企鹅物流般永不停歇。", @@ -76,7 +77,7 @@ func TestAlbum(t *testing.T) { {CID: 125012, Name: "Speed of Light (Instrumental)", Artists: []string{"DJ Okawari"}}, }, Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, - }}, + }, true}, {"detail", &Album{ CID: 1030, @@ -90,7 +91,7 @@ func TestAlbum(t *testing.T) { {CID: 125012, Name: "Speed of Light (Instrumental)", Artists: []string{"DJ Okawari"}}, }, Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, - }, AlbumVariantDetail, &Album{ + }, AlbumVariantDetail, Album{ CID: 1030, Name: "Speed of Light", Intro: "在无人告知方向的黑夜里,独自以光速探寻正确的道路。 \n无论看待世界是简单,亦或是复杂,大地和天空始终让开始与结束相连。 \n《Speed of Light》,通过乐调铺陈的驰放与内敛感,希望能为您呈现超脱于现实的惬意想象空间。 \n愿您掌心的小小地图一直指引着前路。像光一样前行,如企鹅物流般永不停歇。", @@ -101,7 +102,7 @@ func TestAlbum(t *testing.T) { {CID: 880374, Name: "Speed of Light", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}}, {CID: 125012, Name: "Speed of Light (Instrumental)", Artists: []string{"DJ Okawari"}}, }, - }}, + }, true}, {"data", &Album{ CID: 1030, @@ -115,7 +116,7 @@ func TestAlbum(t *testing.T) { {CID: 125012, Name: "Speed of Light (Instrumental)", Artists: []string{"DJ Okawari"}}, }, Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, - }, AlbumVariantData, &Album{ + }, AlbumVariantData, Album{ CID: 1030, Name: "Speed of Light", Intro: "在无人告知方向的黑夜里,独自以光速探寻正确的道路。 \n无论看待世界是简单,亦或是复杂,大地和天空始终让开始与结束相连。 \n《Speed of Light》,通过乐调铺陈的驰放与内敛感,希望能为您呈现超脱于现实的惬意想象空间。 \n愿您掌心的小小地图一直指引着前路。像光一样前行,如企鹅物流般永不停歇。", @@ -123,7 +124,7 @@ func TestAlbum(t *testing.T) { CoverDeURL: "https://web.hycdn.cn/siren/pic/20210322/0bf0d84e08b57acd2455b412224ba8e8.jpg", CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, - }}, + }, true}, {"base", &Album{ CID: 1030, @@ -137,16 +138,20 @@ func TestAlbum(t *testing.T) { {CID: 125012, Name: "Speed of Light (Instrumental)", Artists: []string{"DJ Okawari"}}, }, Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, - }, AlbumVariantBase, &Album{ + }, AlbumVariantBase, Album{ CID: 1030, Name: "Speed of Light", CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, - }}, + }, true}, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - if got := tc.a.Copy(tc.variant); !reflect.DeepEqual(got, tc.want) { + got := Album{CID: -0xdeadbeef} + if ok := tc.a.Copy(&got, tc.variant); ok != tc.wantOk { + t.Errorf("Copy: ok = %v, want %v", ok, tc.wantOk) + } + if !reflect.DeepEqual(got, tc.want) { t.Errorf("Copy: %#v, want %#v", got, tc.want) } }) diff --git a/song.go b/song.go index 0af4303..8260203 100644 --- a/song.go +++ b/song.go @@ -41,34 +41,35 @@ func (s *Song) IsFull() bool { return s.SourceURL != "" } // Copy makes a copy of [Song]. // For a [Song] where the IsFull method returns true, Copy zeroes fields to convert the copy into other variants. // For [Song] where IsFull returns false, any variant other than [SongVariantCurrent] is undefined. -func (s *Song) Copy(variant int) *Song { - if s == nil { - return nil +func (s *Song) Copy(v *Song, variant int) bool { + if v == nil || s == nil || v == s { + return false } - v := *s if variant == SongVariantCurrent { - return &v + *v = *s + return true } if !s.IsFull() { - return nil + return false } switch variant { case SongVariantFull: - break + *v = *s case SongVariantBase: - s.SourceURL = "" - s.LyricURL = "" - s.MvURL = "" - s.MvCoverURL = "" + *v = *s + v.SourceURL = "" + v.LyricURL = "" + v.MvURL = "" + v.MvCoverURL = "" default: - return nil + return false } - return s + return true } // Enrich populates the remaining fields of a non-full [Song]. diff --git a/song_test.go b/song_test.go index c0285a3..17d61cb 100644 --- a/song_test.go +++ b/song_test.go @@ -28,21 +28,22 @@ func TestSong(t *testing.T) { name string a *Song variant int - want *Song + want Song + wantOk bool }{ - {"nil", nil, SongVariantBase, nil}, - {"current", new(Song), SongVariantCurrent, new(Song)}, - {"full guard", new(Song), SongVariantFull, nil}, + {"nil", nil, SongVariantBase, Song{CID: -0xdeadbeef}, false}, + {"current", new(Song), SongVariantCurrent, Song{}, true}, + {"full guard", new(Song), SongVariantFull, Song{CID: -0xdeadbeef}, false}, {"current full", &Song{ SourceURL: "\x00", - }, SongVariantCurrent, &Song{ + }, SongVariantCurrent, Song{ SourceURL: "\x00", - }}, + }, true}, {"oob", &Song{ SourceURL: "\x00", - }, 0xbad, nil}, + }, 0xbad, Song{CID: -0xdeadbeef}, false}, {"full", &Song{ CID: 48794, @@ -51,14 +52,14 @@ func TestSong(t *testing.T) { SourceURL: "https://res01.hycdn.cn/04ce5de54bb52eb85008644d541d40fa/68CA0442/siren/audio/20240709/a7f650238eaefc9c30a9627d7f78d819.wav", LyricURL: "https://web.hycdn.cn/siren/lyric/20240709/4a10c70629b68a187fdbef4a27bd32d8.lrc", Artists: []string{"塞壬唱片-MSR"}, - }, SongVariantFull, &Song{ + }, SongVariantFull, Song{ CID: 48794, Name: "Warm and Small Light", AlbumCID: 6660, SourceURL: "https://res01.hycdn.cn/04ce5de54bb52eb85008644d541d40fa/68CA0442/siren/audio/20240709/a7f650238eaefc9c30a9627d7f78d819.wav", LyricURL: "https://web.hycdn.cn/siren/lyric/20240709/4a10c70629b68a187fdbef4a27bd32d8.lrc", Artists: []string{"塞壬唱片-MSR"}, - }}, + }, true}, {"base", &Song{ CID: 48794, @@ -67,16 +68,20 @@ func TestSong(t *testing.T) { SourceURL: "https://res01.hycdn.cn/04ce5de54bb52eb85008644d541d40fa/68CA0442/siren/audio/20240709/a7f650238eaefc9c30a9627d7f78d819.wav", LyricURL: "https://web.hycdn.cn/siren/lyric/20240709/4a10c70629b68a187fdbef4a27bd32d8.lrc", Artists: []string{"塞壬唱片-MSR"}, - }, SongVariantBase, &Song{ + }, SongVariantBase, Song{ CID: 48794, Name: "Warm and Small Light", AlbumCID: 6660, Artists: []string{"塞壬唱片-MSR"}, - }}, + }, true}, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - if got := tc.a.Copy(tc.variant); !reflect.DeepEqual(got, tc.want) { + got := Song{CID: -0xdeadbeef} + if ok := tc.a.Copy(&got, tc.variant); ok != tc.wantOk { + t.Errorf("Copy: ok = %v, want %v", ok, tc.wantOk) + } + if !reflect.DeepEqual(got, tc.want) { t.Errorf("Copy: %#v, want %#v", got, tc.want) } })