Implement Linux data models (C/Vala)
- Add FeedItem, Feed, FeedSubscription models - Add SearchResult, SearchFilters, SearchQuery models - Add NotificationPreferences, ReadingPreferences models - Implement JSON serialization/deserialization for all models - Add equality comparison methods - Following GNOME HIG naming conventions - Build system configured with Meson/Ninja
This commit is contained in:
208
native-route/linux/src/models/search-result.vala
Normal file
208
native-route/linux/src/models/search-result.vala
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* SearchResult.vala
|
||||
*
|
||||
* Represents a search result item from the feed database.
|
||||
* Following GNOME HIG naming conventions and Vala/GObject patterns.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SearchResultType - Type of search result
|
||||
*/
|
||||
public enum RSSuper.SearchResultType {
|
||||
ARTICLE,
|
||||
FEED
|
||||
}
|
||||
|
||||
/**
|
||||
* SearchResult - Represents a single search result
|
||||
*/
|
||||
public class RSSuper.SearchResult : Object {
|
||||
public string id { get; set; }
|
||||
public SearchResultType result_type { get; set; }
|
||||
public string title { get; set; }
|
||||
public string? snippet { get; set; }
|
||||
public string? link { get; set; }
|
||||
public string? feed_title { get; set; }
|
||||
public string? published { get; set; }
|
||||
public double score { get; set; }
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public SearchResult() {
|
||||
this.id = "";
|
||||
this.result_type = SearchResultType.ARTICLE;
|
||||
this.title = "";
|
||||
this.score = 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with initial values
|
||||
*/
|
||||
public SearchResult.with_values(string id, SearchResultType type, string title,
|
||||
string? snippet = null, string? link = null,
|
||||
string? feed_title = null, string? published = null,
|
||||
double score = 0.0) {
|
||||
this.id = id;
|
||||
this.result_type = type;
|
||||
this.title = title;
|
||||
this.snippet = snippet;
|
||||
this.link = link;
|
||||
this.feed_title = feed_title;
|
||||
this.published = published;
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get type as string
|
||||
*/
|
||||
public string get_type_string() {
|
||||
switch (this.result_type) {
|
||||
case SearchResultType.ARTICLE:
|
||||
return "article";
|
||||
case SearchResultType.FEED:
|
||||
return "feed";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse type from string
|
||||
*/
|
||||
public static SearchResultType type_from_string(string str) {
|
||||
switch (str) {
|
||||
case "article":
|
||||
return SearchResultType.ARTICLE;
|
||||
case "feed":
|
||||
return SearchResultType.FEED;
|
||||
default:
|
||||
return SearchResultType.ARTICLE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize to JSON string
|
||||
*/
|
||||
public string to_json_string() {
|
||||
var sb = new StringBuilder();
|
||||
sb.append("{");
|
||||
sb.append("\"id\":\"");
|
||||
sb.append(this.id);
|
||||
sb.append("\",\"type\":\"");
|
||||
sb.append(this.get_type_string());
|
||||
sb.append("\",\"title\":\"");
|
||||
sb.append(this.title);
|
||||
sb.append("\"");
|
||||
|
||||
if (this.snippet != null) {
|
||||
sb.append(",\"snippet\":\"");
|
||||
sb.append(this.snippet);
|
||||
sb.append("\"");
|
||||
}
|
||||
if (this.link != null) {
|
||||
sb.append(",\"link\":\"");
|
||||
sb.append(this.link);
|
||||
sb.append("\"");
|
||||
}
|
||||
if (this.feed_title != null) {
|
||||
sb.append(",\"feedTitle\":\"");
|
||||
sb.append(this.feed_title);
|
||||
sb.append("\"");
|
||||
}
|
||||
if (this.published != null) {
|
||||
sb.append(",\"published\":\"");
|
||||
sb.append(this.published);
|
||||
sb.append("\"");
|
||||
}
|
||||
if (this.score != 0.0) {
|
||||
sb.append(",\"score\":%f".printf(this.score));
|
||||
}
|
||||
|
||||
sb.append("}");
|
||||
return sb.str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize from JSON string
|
||||
*/
|
||||
public static SearchResult? 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 SearchResult? 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("type") || !obj.has_member("title")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var result = new SearchResult();
|
||||
result.id = obj.get_string_member("id");
|
||||
result.result_type = SearchResult.type_from_string(obj.get_string_member("type"));
|
||||
result.title = obj.get_string_member("title");
|
||||
|
||||
if (obj.has_member("snippet")) {
|
||||
result.snippet = obj.get_string_member("snippet");
|
||||
}
|
||||
if (obj.has_member("link")) {
|
||||
result.link = obj.get_string_member("link");
|
||||
}
|
||||
if (obj.has_member("feedTitle")) {
|
||||
result.feed_title = obj.get_string_member("feedTitle");
|
||||
}
|
||||
if (obj.has_member("published")) {
|
||||
result.published = obj.get_string_member("published");
|
||||
}
|
||||
if (obj.has_member("score")) {
|
||||
result.score = obj.get_double_member("score");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Equality comparison
|
||||
*/
|
||||
public bool equals(SearchResult? other) {
|
||||
if (other == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.id == other.id &&
|
||||
this.result_type == other.result_type &&
|
||||
this.title == other.title &&
|
||||
this.snippet == other.snippet &&
|
||||
this.link == other.link &&
|
||||
this.feed_title == other.feed_title &&
|
||||
this.published == other.published &&
|
||||
this.score == other.score;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a human-readable summary
|
||||
*/
|
||||
public string get_summary() {
|
||||
if (this.feed_title != null) {
|
||||
return "[%s] %s - %s".printf(this.get_type_string(), this.feed_title, this.title);
|
||||
}
|
||||
return "[%s] %s".printf(this.get_type_string(), this.title);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user