laburnum 1.17.0

An LSP framework for building language servers and compilers, powered by an incremental query tree with content-addressed storage, task-based dataflow, and parallel queries.
Documentation
// Copyright Two Neutron Stars Incorporated and contributors
// SPDX-License-Identifier: BlueOak-1.0.0

use crate::{
  Ident,
  database::{
    DynPartition,
    PartitionKey,
  },
  protocol::lsp,
};

pub struct WorkDoneProgress;

#[derive(Debug, Clone)]
pub enum WorkDoneProgressSortKey {
  Token { token: String },
}

impl std::fmt::Display for WorkDoneProgressSortKey {
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    match self {
      | WorkDoneProgressSortKey::Token { token } => write!(f, "{}", token),
    }
  }
}

impl PartitionKey for WorkDoneProgress {
  const KEY: Ident = Ident::new("laburnum::work_done_progress");
}
/// To write work done progress, create a wrapper partition with
/// [`impl_partition_for_dyn!`]:
///
/// ```rust,ignore
/// use laburnum::{impl_partition_for_dyn, partitions::WorkDoneProgress};
///
/// // Your record type must implement WorkDoneProgressRecord + Record
/// impl_partition_for_dyn!(MyProgressPartition, WorkDoneProgress, MyProgress);
///
/// // Then write using the wrapper partition
/// let sort_key = WorkDoneProgressSortKey::Token { token: token.to_string() };
/// writer.write::<MyProgressPartition>(sort_key, progress.into());
/// ```
///
/// [`impl_partition_for_dyn!`]: crate::impl_partition_for_dyn
impl DynPartition for WorkDoneProgress {
  type DynSortKey = WorkDoneProgressSortKey;
  type RecordConstraint = dyn WorkDoneProgressRecord;
}

impl<R: WorkDoneProgressRecord + crate::record::Record>
  crate::database::DynPartitionRecord<WorkDoneProgress> for R
{
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ProgressStage {
  Begin,
  Report,
  End,
}

pub trait WorkDoneProgressRecord: Send + Sync + std::fmt::Debug {
  fn stage(&self) -> ProgressStage;

  fn title(&self) -> Option<&str>;

  fn message(&self) -> Option<&str>;

  fn percentage(&self) -> Option<u32>;

  fn cancellable(&self) -> Option<bool>;

  fn to_lsp_progress(&self) -> lsp::WorkDoneProgress {
    match self.stage() {
      | ProgressStage::Begin => {
        lsp::WorkDoneProgress::Begin(lsp::WorkDoneProgressBegin {
          title:       self.title().unwrap_or("Working").to_string(),
          cancellable: self.cancellable(),
          message:     self.message().map(String::from),
          percentage:  self.percentage(),
        })
      },
      | ProgressStage::Report => {
        lsp::WorkDoneProgress::Report(lsp::WorkDoneProgressReport {
          cancellable: self.cancellable(),
          message:     self.message().map(String::from),
          percentage:  self.percentage(),
        })
      },
      | ProgressStage::End => {
        lsp::WorkDoneProgress::End(lsp::WorkDoneProgressEnd {
          message: self.message().map(String::from),
        })
      },
    }
  }

  fn token(&self) -> &str;
}