Repository: sxyazi/yazi
File: yazi-plugin/src/elements/span.rs (Rust)

Code before:
use mlua::{ExternalError, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
use unicode_width::UnicodeWidthChar;

const EXPECTED: &str = "expected a string or Span";

pub struct Span(pub(super) ratatui::text::Span<'static>);

impl Span {
	pub fn compose(lua: &Lua) -> mlua::Result<Table> {
		let new = lua.create_function(|_, (_, value): (Table, Value)| Span::try_from(value))?;

		let span = lua.create_table()?;
		span.set_metatable(Some(lua.create_table_from([(MetaMethod::Call.name(), new)])?));

		Ok(span)
	}
}

impl TryFrom<Value> for Span {
	type Error = mlua::Error;

	fn try_from(value: Value) -> Result<Self, Self::Error> {
		Ok(Self(match value {
			Value::String(s) => s.to_string_lossy().into(),
			Value::UserData(ud) => {
				if let Ok(Span(span)) = ud.take() {
					span
				} else {
					Err(EXPECTED.into_lua_err())?
				}
			}
			_ => Err(EXPECTED.into_lua_err())?,
		}))
	}
}

impl UserData for Span {
	fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
		crate::impl_style_method!(methods, 0.style);
		crate::impl_style_shorthands!(methods, 0.style);

		methods.add_method("visible", |_, Span(me), ()| {
			Ok(me.content.chars().any(|c| c.width().unwrap_or(0) > 0))
		});

Review comment (bug):
[nitpick] Add a Rust doc comment explaining what the returned `usize` represents (e.g., the width of the ellipsis or consumed characters) and how edge cases are handled.
```suggestion

	/// Truncates the content of the `Span` to fit within the specified maximum width.
	///
	/// # Arguments
	/// * `max` - The maximum width (in Unicode character widths) to which the content should be truncated.
	///
	/// # Returns
	/// The width of the truncated content, including the ellipsis if added.
	///
	/// # Edge Cases
	/// * If `max` is less than 1, the content is cleared, and `0` is returned.
	/// * If the content already fits within `max`, it remains unchanged, and its width is returned.
```

Code after:
use std::borrow::Cow;

use mlua::{AnyUserData, ExternalError, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
use unicode_width::UnicodeWidthChar;

const EXPECTED: &str = "expected a string or Span";

pub struct Span(pub(super) ratatui::text::Span<'static>);

impl Span {
	pub fn compose(lua: &Lua) -> mlua::Result<Table> {
		let new = lua.create_function(|_, (_, value): (Table, Value)| Span::try_from(value))?;

		let span = lua.create_table()?;
		span.set_metatable(Some(lua.create_table_from([(MetaMethod::Call.name(), new)])?));

		Ok(span)
	}

	pub(super) fn truncate(&mut self, max: usize) -> usize {
		if max < 1 {
			match &mut self.0.content {
				Cow::Borrowed(_) => self.0.content = Cow::Borrowed(""),
				Cow::Owned(s) => s.clear(),
			}
			return 0;
		}

		let mut adv = 0;
		let mut last;
		for (i, c) in self.0.content.char_indices() {
			(last, adv) = (adv, adv + c.width().unwrap_or(0));
			if adv < max {
				continue;
			} else if adv == max && self.0.content[i..].chars().nth(1).is_none() {
				return max;
			}
			match &mut self.0.content {
				Cow::Borrowed(s) => self.0.content = format!("{}…", &s[..i]).into(),
				Cow::Owned(s) => {
					s.truncate(i);
					s.push('…');
				}
			}