use async_trait::async_trait;
use super::{ContentSource, Named, SourceType};
#[async_trait]
pub trait Index: Named + Clone + Send + Sync + 'static {
fn source(&self) -> &ContentSource;
fn source_type(&self) -> SourceType;
fn priority(&self) -> i32 {
match self.source_type() {
SourceType::Project => 20,
SourceType::User => 10,
SourceType::Managed => 5,
SourceType::Builtin => 0,
SourceType::Plugin => -5,
}
}
fn to_summary_line(&self) -> String;
async fn load_content(&self) -> crate::Result<String> {
self.source().load().await
}
fn description(&self) -> &str {
""
}
}
#[cfg(test)]
mod tests {
use async_trait::async_trait;
use super::*;
use crate::common::Named;
#[derive(Clone, Debug)]
struct TestIndex {
name: String,
desc: String,
source: ContentSource,
source_type: SourceType,
}
impl Named for TestIndex {
fn name(&self) -> &str {
&self.name
}
}
#[async_trait]
impl Index for TestIndex {
fn source(&self) -> &ContentSource {
&self.source
}
fn source_type(&self) -> SourceType {
self.source_type
}
fn to_summary_line(&self) -> String {
format!("- {}: {}", self.name, self.desc)
}
fn description(&self) -> &str {
&self.desc
}
}
#[test]
fn test_priority_ordering() {
let builtin = TestIndex {
name: "test".into(),
desc: "desc".into(),
source: ContentSource::in_memory(""),
source_type: SourceType::Builtin,
};
let user = TestIndex {
name: "test".into(),
desc: "desc".into(),
source: ContentSource::in_memory(""),
source_type: SourceType::User,
};
let project = TestIndex {
name: "test".into(),
desc: "desc".into(),
source: ContentSource::in_memory(""),
source_type: SourceType::Project,
};
let plugin = TestIndex {
name: "test".into(),
desc: "desc".into(),
source: ContentSource::in_memory(""),
source_type: SourceType::Plugin,
};
assert!(project.priority() > user.priority());
assert!(user.priority() > builtin.priority());
assert!(builtin.priority() > plugin.priority());
assert_eq!(plugin.priority(), -5);
}
#[tokio::test]
async fn test_load_content() {
let index = TestIndex {
name: "test".into(),
desc: "desc".into(),
source: ContentSource::in_memory("full content here"),
source_type: SourceType::User,
};
let content = index.load_content().await.unwrap();
assert_eq!(content, "full content here");
}
#[test]
fn test_summary_line() {
let index = TestIndex {
name: "commit".into(),
desc: "Create git commits".into(),
source: ContentSource::in_memory(""),
source_type: SourceType::User,
};
assert_eq!(index.to_summary_line(), "- commit: Create git commits");
}
}