krz/moonrise

Night-sky companion for iPhone, Apple Watch and Vision Pro: what's up tonight, the Moon, planets, launches and missions, and a Library of the solar system. SwiftUI app with a Cloudflare Workers backend. astronomy cloudflare-workers ios night-sky space swiftui visionos watchos

Packages/MoonriseKit/Sources/Library/Tours.swift

04b2b1d914788057bcd20945b876847386eb8f65
moonrise/Packages/MoonriseKit/Sources/Library/Tours.swift history · blame · raw

49 lines · 1778 bytes

4 symbols in this file
 1import Foundation
 2
 3/// A guided walk around one season's evening sky.
 4public struct Tour: Sendable, Decodable, Identifiable {
 5    public struct Target: Sendable, Decodable, Hashable {
 6        /// IAU abbreviation, e.g. "Ori".
 7        public var constellation: String?
 8        public var hr: Int?
 9        /// Body raw value, e.g. "jupiter".
10        public var body: String?
11    }
12
13    public struct Step: Sendable, Decodable, Hashable {
14        public var title: String
15        public var target: Target
16        public var text: String
17        /// Library page to open, when it is not the target's own page.
18        public var page: String?
19    }
20
21    public var id: String
22    public var title: String
23    /// Months (1–12) when the tour's stars are up in the evening (the same in both hemispheres).
24    public var months: [Int]
25    public var intro: String
26    public var steps: [Step]
27
28    public static let all: [Tour] = {
29        let url = Bundle.module.url(forResource: "tours", withExtension: "json", subdirectory: "tours")!
30        return try! JSONDecoder().decode([Tour].self, from: Data(contentsOf: url))
31    }()
32
33    /// Tours in order from the one for `month` onwards.
34    public static func ordered(month: Int) -> [Tour] {
35        let start = all.firstIndex { $0.months.contains(month) } ?? 0
36        return Array(all[start...] + all[..<start])
37    }
38}
39
40extension Tour.Step {
41    /// The step's own Library page, else the target's.
42    public var libraryPage: LibraryPage? {
43        if let page { return Library.page(id: page) }
44        if let hr = target.hr { return Library.page(hr: hr) }
45        if let c = target.constellation { return Library.page(constellation: c) }
46        if let b = target.body { return Library.page(body: b) }
47        return nil
48    }
49}