import Foundation
/// Holds information, content and the activity history of a user.
public struct Profile: Hashable, Sendable {
/// The user's alias.
public let username: String
/// The number of upvotes that the user got from other users.
public let score: Int
/// The time when the user created the account.
public let created: Date
/// The description of the user.
public let about: String?
/// The description of the geographic location.
public let location: String?
/// The description of the user's skills.
public let skills: String?
/// The user's GitHub reference.
public let github: String?
/// The user's personal website.
public let website: String?
/// The user's content and activities.
public let content: Content
/// The user's large avatar, for profile views.
public let avatarLarge: User.Avatar
/// The user's small avatar, for rant views and comment views.
public let avatarSmall: User.Avatar
/// True if the user is subscribed to devRant++.
public let devRantSupporter: Bool
/// True if the logged in user is subscribed to the user of this profile.
public var subscribed: Bool
public init(username: String, score: Int, created: Date, about: String?, location: String?, skills: String?, github: String?, website: String?, content: Profile.Content, avatarLarge: User.Avatar, avatarSmall: User.Avatar, devRantSupporter: Bool, subscribed: Bool) {
self.username = username
self.score = score
self.created = created
self.about = about
self.location = location
self.skills = skills
self.github = github
self.website = website
self.content = content
self.avatarLarge = avatarLarge
self.avatarSmall = avatarSmall
self.devRantSupporter = devRantSupporter
self.subscribed = subscribed
}
}
public extension Profile {
enum ContentType: String, Sendable {
/// All user content.
case all = "all"
/// The user's rants.
case rants = "rants"
/// The user's comments.
case comments = "comments"
/// Rants or comments upvoted by the user.
case upvoted = "upvoted"
/// The user's favorite rants.
case favorite = "favorites"
/// The rants viewd by the user.
case viewed = "viewed"
}
}
extension Profile {
struct CodingData: Codable {
struct Container: Codable {
let profile: Profile.CodingData
let subscribed: Int?
}
let username: String
let score: Int
let created_time: Int
let about: String
let location: String
let skills: String
let github: String
let website: String
let content: Content.CodingData
let avatar: User.Avatar.CodingData
let avatar_sm: User.Avatar.CodingData
let dpp: Int?
}
}
extension Profile.CodingData.Container {
var decoded: Profile {
return .init(
username: profile.username,
score: profile.score,
created: Date(timeIntervalSince1970: TimeInterval(profile.created_time)),
about: profile.about.isEmpty ? nil : profile.about,
location: profile.location.isEmpty ? nil : profile.location,
skills: profile.skills.isEmpty ? nil : profile.skills,
github: profile.github.isEmpty ? nil : profile.github,
website: profile.website.isEmpty ? nil : profile.website,
content: profile.content.decoded,
avatarLarge: profile.avatar.decoded,
avatarSmall: profile.avatar_sm.decoded,
devRantSupporter: (profile.dpp ?? 0) != 0,
subscribed: (subscribed ?? 0) != 0
)
}
}