/* * Bookmark.vala * * Represents a bookmarked feed item. * Following GNOME HIG naming conventions and Vala/GObject patterns. */ /** * Bookmark - Represents a bookmarked feed item */ public class RSSuper.Bookmark : Object { public string id { get; set; } public string feed_item_id { get; set; } public string title { get; set; } public string? link { get; set; } public string? description { get; set; } public string? content { get; set; } public string created_at { get; set; } public string? tags { get; set; } /** * Default constructor */ public Bookmark() { this.id = ""; this.feed_item_id = ""; this.title = ""; this.created_at = ""; } /** * Constructor with initial values */ public Bookmark.with_values(string id, string feed_item_id, string title, string? link = null, string? description = null, string? content = null, string? created_at = null, string? tags = null) { this.id = id; this.feed_item_id = feed_item_id; this.title = title; this.link = link; this.description = description; this.content = content; this.created_at = created_at ?? DateTime.now_local().format("%Y-%m-%dT%H:%M:%S"); this.tags = tags; } /** * Serialize to JSON string */ public string to_json_string() { var sb = new StringBuilder(); sb.append("{"); sb.append("\"id\":\""); sb.append(this.id); sb.append("\",\"feedItemId\":\""); sb.append(this.feed_item_id); sb.append("\",\"title\":\""); sb.append(this.title); sb.append("\""); if (this.link != null) { sb.append(",\"link\":\""); sb.append(this.link); sb.append("\""); } if (this.description != null) { sb.append(",\"description\":\""); sb.append(this.description); sb.append("\""); } if (this.content != null) { sb.append(",\"content\":\""); sb.append(this.content); sb.append("\""); } if (this.created_at != null) { sb.append(",\"createdAt\":\""); sb.append(this.created_at); sb.append("\""); } if (this.tags != null) { sb.append(",\"tags\":\""); sb.append(this.tags); sb.append("\""); } sb.append("}"); return sb.str; } /** * Deserialize from JSON string */ public static Bookmark? from_json_string(string json_string) { var parser = new Json.Parser(); try { if (!parser.load_from_data(json_string)) { return null; } } catch (Error e) { warning("Failed to parse JSON: %s", e.message); return null; } return from_json_node(parser.get_root()); } /** * Deserialize from Json.Node */ public static Bookmark? from_json_node(Json.Node node) { if (node.get_node_type() != Json.NodeType.OBJECT) { return null; } var obj = node.get_object(); if (!obj.has_member("id") || !obj.has_member("feedItemId") || !obj.has_member("title")) { return null; } var bookmark = new Bookmark(); bookmark.id = obj.get_string_member("id"); bookmark.feed_item_id = obj.get_string_member("feedItemId"); bookmark.title = obj.get_string_member("title"); if (obj.has_member("link")) { bookmark.link = obj.get_string_member("link"); } if (obj.has_member("description")) { bookmark.description = obj.get_string_member("description"); } if (obj.has_member("content")) { bookmark.content = obj.get_string_member("content"); } if (obj.has_member("createdAt")) { bookmark.created_at = obj.get_string_member("createdAt"); } if (obj.has_member("tags")) { bookmark.tags = obj.get_string_member("tags"); } return bookmark; } /** * Equality comparison */ public bool equals(Bookmark? other) { if (other == null) { return false; } return this.id == other.id && this.feed_item_id == other.feed_item_id && this.title == other.title && this.link == other.link && this.description == other.description && this.content == other.content && this.created_at == other.created_at && this.tags == other.tags; } /** * Get a human-readable summary */ public string get_summary() { return "[%s] %s".printf(this.feed_item_id, this.title); } }