Fine(isize, usize), // line #n of this item is just off bottom of screen
}
-struct FeedFileContents {
+trait FeedType {
+ type Item: TextFragment + Sized;
+
+ fn get_from_client(id: &str, client: &mut Client) ->
+ Result<Self::Item, ClientError>;
+}
+
+struct StatusFeedType {}
+impl FeedType for StatusFeedType {
+ type Item = StatusDisplay;
+
+ fn get_from_client(id: &str, client: &mut Client) ->
+ Result<Self::Item, ClientError>
+ {
+ let st = client.status_by_id(&id)?;
+ Ok(StatusDisplay::new(st.clone(), client))
+ }
+}
+
+struct FeedFileContents<Type: FeedType> {
id: FeedId,
header: FileHeader,
extender: Option<ExtendableIndicator>,
origin: isize,
- items: Vec<Box<dyn TextFragment>>,
+ items: Vec<Type::Item>,
}
-impl FeedFileContents {
+impl<Type: FeedType> FeedFileContents<Type> {
fn update_items(&mut self, client: &mut Client) {
// FIXME: if the feed has been extended rather than created,
// we should be able to make less effort than this
self.items.clear();
for id in ids {
- let st = client.status_by_id(&id)
- .expect("Any id stored in a Feed should also be cached")
- .clone();
- self.items.push(Box::new(StatusDisplay::new(st, client)));
+ let item = Type::get_from_client(&id, client)
+ .expect("Any id stored in a Feed should also be cached");
+ self.items.push(item);
}
}
}
} else {
let index = self.phys_index(index);
- &*self.items[index]
+ &self.items[index]
}
}
}
-struct FeedFile {
- contents: FeedFileContents,
+struct FeedFile<Type: FeedType> {
+ contents: FeedFileContents<Type>,
rendered: HashMap<isize, Vec<ColouredString>>,
pos: FilePosition,
last_size: Option<(usize, usize)>,
}
-impl FeedFile {
+impl<Type: FeedType> FeedFile<Type> {
fn new(client: &mut Client, id: FeedId, desc: ColouredString) ->
Result<Self, ClientError>
{
}
}
-impl ActivityState for FeedFile {
+impl<Type: FeedType> ActivityState for FeedFile<Type> {
fn resize(&mut self, w: usize, h: usize) {
if self.last_size != Some((w, h)) {
self.last_size = Some((w, h));
pub fn home_timeline(client: &mut Client) ->
Result<Box<dyn ActivityState>, ClientError>
{
- let file = FeedFile::new(client, FeedId::Home, ColouredString::general(
- "Home timeline <H>",
- "HHHHHHHHHHHHHHHHHKH"))?;
+ let file = FeedFile::<StatusFeedType>::new(
+ client, FeedId::Home, ColouredString::general(
+ "Home timeline <H>",
+ "HHHHHHHHHHHHHHHHHKH"))?;
Ok(Box::new(file))
}
pub fn local_timeline(client: &mut Client) ->
Result<Box<dyn ActivityState>, ClientError>
{
- let file = FeedFile::new(client, FeedId::Local, ColouredString::general(
- "Local public timeline <L>",
- "HHHHHHHHHHHHHHHHHHHHHHHHHKH"))?;
+ let file = FeedFile::<StatusFeedType>::new(
+ client, FeedId::Local, ColouredString::general(
+ "Local public timeline <L>",
+ "HHHHHHHHHHHHHHHHHHHHHHHHHKH"))?;
Ok(Box::new(file))
}
pub fn public_timeline(client: &mut Client) ->
Result<Box<dyn ActivityState>, ClientError>
{
- let file = FeedFile::new(client, FeedId::Public, ColouredString::general(
- "Public timeline <P>",
- "HHHHHHHHHHHHHHHHHHHKH"))?;
+ let file = FeedFile::<StatusFeedType>::new(
+ client, FeedId::Public, ColouredString::general(
+ "Public timeline <P>",
+ "HHHHHHHHHHHHHHHHHHHKH"))?;
Ok(Box::new(file))
}