use std::fmt::{self, Debug, Display, Formatter};
use std::ops::Deref;
use crate::grapheme::graphemes;
use crate::grapheme::policy_ext::{
display_width_with_policy, display_widths_with_policy, grapheme_widths_with_policy,
split_by_width_with_policy, truncate_by_width_with_policy,
};
use crate::policy::WidthPolicy;
pub struct WithPolicy<'a> {
policy: &'a WidthPolicy,
}
impl<'a> WithPolicy<'a> {
pub fn new(policy: &'a WidthPolicy) -> Self {
Self { policy }
}
pub fn apply<'s>(&'a self, input: &'s str) -> AppliedPolicy<'a, 's> {
AppliedPolicy {
s: input,
policy: self.policy,
}
}
}
pub struct AppliedPolicy<'a, 's> {
s: &'s str,
policy: &'a WidthPolicy,
}
impl AppliedPolicy<'_, '_> {
pub fn graphemes(&self) -> Vec<&str> {
graphemes(self.s)
}
pub fn display_width(&self) -> usize {
display_width_with_policy(self.s, Some(self.policy))
}
pub fn display_widths(&self) -> Vec<usize> {
display_widths_with_policy(self.s, Some(self.policy))
}
pub fn widths_grapheme(&self) -> Vec<(&str, usize)> {
grapheme_widths_with_policy(self.s, Some(self.policy))
}
pub fn truncate_by_width(&self, max_width: usize) -> &str {
truncate_by_width_with_policy(self.s, max_width, Some(self.policy))
}
pub fn split_by_width(&self, max_width: usize) -> Vec<String> {
split_by_width_with_policy(self.s, max_width, Some(self.policy))
}
}
impl Display for AppliedPolicy<'_, '_> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.s)
}
}
impl Debug for AppliedPolicy<'_, '_> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("AppliedPolicy")
.field("text", &self.s)
.field("display_width", &self.display_width())
.finish()
}
}
impl AsRef<str> for AppliedPolicy<'_, '_> {
fn as_ref(&self) -> &str {
self.s
}
}
impl Deref for AppliedPolicy<'_, '_> {
type Target = str;
fn deref(&self) -> &Self::Target {
self.s
}
}
impl PartialEq<str> for AppliedPolicy<'_, '_> {
fn eq(&self, other: &str) -> bool {
self.s == other
}
}
impl PartialEq<&str> for AppliedPolicy<'_, '_> {
fn eq(&self, other: &&str) -> bool {
self.s == *other
}
}