mirror of
https://github.com/martinvonz/jj.git
synced 2025-05-28 10:31:14 +00:00
templater: add type_name() method to tagged property types
Suppose we add binary comparison operators, we'll probably need an easy way to get (lhs, rhs) property types to produce a meaningful error message.
This commit is contained in:
parent
5b769c5c9e
commit
5394f342ce
@ -115,6 +115,7 @@ impl<'repo> TemplateLanguage<'repo> for CommitTemplateLanguage<'repo> {
|
||||
property: Self::Property,
|
||||
function: &FunctionCallNode,
|
||||
) -> TemplateParseResult<Self::Property> {
|
||||
let type_name = property.type_name();
|
||||
match property {
|
||||
CommitTemplatePropertyKind::Core(property) => {
|
||||
let table = &self.build_fn_table.core;
|
||||
@ -122,12 +123,13 @@ impl<'repo> TemplateLanguage<'repo> for CommitTemplateLanguage<'repo> {
|
||||
}
|
||||
CommitTemplatePropertyKind::Commit(property) => {
|
||||
let table = &self.build_fn_table.commit_methods;
|
||||
let build = template_parser::lookup_method("Commit", table, function)?;
|
||||
let build = template_parser::lookup_method(type_name, table, function)?;
|
||||
build(self, build_ctx, property, function)
|
||||
}
|
||||
CommitTemplatePropertyKind::CommitOpt(property) => {
|
||||
let type_name = "Commit";
|
||||
let table = &self.build_fn_table.commit_methods;
|
||||
let build = template_parser::lookup_method("Commit", table, function)?;
|
||||
let build = template_parser::lookup_method(type_name, table, function)?;
|
||||
let inner_property = property.and_then(|opt| {
|
||||
opt.ok_or_else(|| TemplatePropertyError("No commit available".into()))
|
||||
});
|
||||
@ -145,12 +147,13 @@ impl<'repo> TemplateLanguage<'repo> for CommitTemplateLanguage<'repo> {
|
||||
}
|
||||
CommitTemplatePropertyKind::RefName(property) => {
|
||||
let table = &self.build_fn_table.ref_name_methods;
|
||||
let build = template_parser::lookup_method("RefName", table, function)?;
|
||||
let build = template_parser::lookup_method(type_name, table, function)?;
|
||||
build(self, build_ctx, property, function)
|
||||
}
|
||||
CommitTemplatePropertyKind::RefNameOpt(property) => {
|
||||
let type_name = "RefName";
|
||||
let table = &self.build_fn_table.ref_name_methods;
|
||||
let build = template_parser::lookup_method("RefName", table, function)?;
|
||||
let build = template_parser::lookup_method(type_name, table, function)?;
|
||||
let inner_property = property.and_then(|opt| {
|
||||
opt.ok_or_else(|| TemplatePropertyError("No RefName available".into()))
|
||||
});
|
||||
@ -168,12 +171,12 @@ impl<'repo> TemplateLanguage<'repo> for CommitTemplateLanguage<'repo> {
|
||||
}
|
||||
CommitTemplatePropertyKind::CommitOrChangeId(property) => {
|
||||
let table = &self.build_fn_table.commit_or_change_id_methods;
|
||||
let build = template_parser::lookup_method("CommitOrChangeId", table, function)?;
|
||||
let build = template_parser::lookup_method(type_name, table, function)?;
|
||||
build(self, build_ctx, property, function)
|
||||
}
|
||||
CommitTemplatePropertyKind::ShortestIdPrefix(property) => {
|
||||
let table = &self.build_fn_table.shortest_id_prefix_methods;
|
||||
let build = template_parser::lookup_method("ShortestIdPrefix", table, function)?;
|
||||
let build = template_parser::lookup_method(type_name, table, function)?;
|
||||
build(self, build_ctx, property, function)
|
||||
}
|
||||
}
|
||||
@ -261,6 +264,20 @@ pub enum CommitTemplatePropertyKind<'repo> {
|
||||
}
|
||||
|
||||
impl<'repo> IntoTemplateProperty<'repo> for CommitTemplatePropertyKind<'repo> {
|
||||
fn type_name(&self) -> &'static str {
|
||||
match self {
|
||||
CommitTemplatePropertyKind::Core(property) => property.type_name(),
|
||||
CommitTemplatePropertyKind::Commit(_) => "Commit",
|
||||
CommitTemplatePropertyKind::CommitOpt(_) => "Option<Commit>",
|
||||
CommitTemplatePropertyKind::CommitList(_) => "List<Commit>",
|
||||
CommitTemplatePropertyKind::RefName(_) => "RefName",
|
||||
CommitTemplatePropertyKind::RefNameOpt(_) => "Option<RefName>",
|
||||
CommitTemplatePropertyKind::RefNameList(_) => "List<RefName>",
|
||||
CommitTemplatePropertyKind::CommitOrChangeId(_) => "CommitOrChangeId",
|
||||
CommitTemplatePropertyKind::ShortestIdPrefix(_) => "ShortestIdPrefix",
|
||||
}
|
||||
}
|
||||
|
||||
fn try_into_boolean(self) -> Option<Box<dyn TemplateProperty<Output = bool> + 'repo>> {
|
||||
match self {
|
||||
CommitTemplatePropertyKind::Core(property) => property.try_into_boolean(),
|
||||
|
@ -94,6 +94,7 @@ impl<'a, C: 'a> TemplateLanguage<'a> for GenericTemplateLanguage<'a, C> {
|
||||
property: Self::Property,
|
||||
function: &FunctionCallNode,
|
||||
) -> TemplateParseResult<Self::Property> {
|
||||
let type_name = property.type_name();
|
||||
match property {
|
||||
GenericTemplatePropertyKind::Core(property) => {
|
||||
let table = &self.build_fn_table.core;
|
||||
@ -101,7 +102,7 @@ impl<'a, C: 'a> TemplateLanguage<'a> for GenericTemplateLanguage<'a, C> {
|
||||
}
|
||||
GenericTemplatePropertyKind::Self_(property) => {
|
||||
let table = &self.build_fn_table.keywords;
|
||||
let build = template_parser::lookup_method("Self", table, function)?;
|
||||
let build = template_parser::lookup_method(type_name, table, function)?;
|
||||
// For simplicity, only 0-ary method is supported.
|
||||
template_parser::expect_no_arguments(function)?;
|
||||
build(property)
|
||||
@ -124,6 +125,13 @@ pub enum GenericTemplatePropertyKind<'a, C> {
|
||||
}
|
||||
|
||||
impl<'a, C: 'a> IntoTemplateProperty<'a> for GenericTemplatePropertyKind<'a, C> {
|
||||
fn type_name(&self) -> &'static str {
|
||||
match self {
|
||||
GenericTemplatePropertyKind::Core(property) => property.type_name(),
|
||||
GenericTemplatePropertyKind::Self_(_) => "Self",
|
||||
}
|
||||
}
|
||||
|
||||
fn try_into_boolean(self) -> Option<Box<dyn TemplateProperty<Output = bool> + 'a>> {
|
||||
match self {
|
||||
GenericTemplatePropertyKind::Core(property) => property.try_into_boolean(),
|
||||
|
@ -92,6 +92,7 @@ impl TemplateLanguage<'static> for OperationTemplateLanguage {
|
||||
property: Self::Property,
|
||||
function: &FunctionCallNode,
|
||||
) -> TemplateParseResult<Self::Property> {
|
||||
let type_name = property.type_name();
|
||||
match property {
|
||||
OperationTemplatePropertyKind::Core(property) => {
|
||||
let table = &self.build_fn_table.core;
|
||||
@ -99,12 +100,12 @@ impl TemplateLanguage<'static> for OperationTemplateLanguage {
|
||||
}
|
||||
OperationTemplatePropertyKind::Operation(property) => {
|
||||
let table = &self.build_fn_table.operation_methods;
|
||||
let build = template_parser::lookup_method("Operation", table, function)?;
|
||||
let build = template_parser::lookup_method(type_name, table, function)?;
|
||||
build(self, build_ctx, property, function)
|
||||
}
|
||||
OperationTemplatePropertyKind::OperationId(property) => {
|
||||
let table = &self.build_fn_table.operation_id_methods;
|
||||
let build = template_parser::lookup_method("OperationId", table, function)?;
|
||||
let build = template_parser::lookup_method(type_name, table, function)?;
|
||||
build(self, build_ctx, property, function)
|
||||
}
|
||||
}
|
||||
@ -136,6 +137,14 @@ pub enum OperationTemplatePropertyKind {
|
||||
}
|
||||
|
||||
impl IntoTemplateProperty<'static> for OperationTemplatePropertyKind {
|
||||
fn type_name(&self) -> &'static str {
|
||||
match self {
|
||||
OperationTemplatePropertyKind::Core(property) => property.type_name(),
|
||||
OperationTemplatePropertyKind::Operation(_) => "Operation",
|
||||
OperationTemplatePropertyKind::OperationId(_) => "OperationId",
|
||||
}
|
||||
}
|
||||
|
||||
fn try_into_boolean(self) -> Option<Box<dyn TemplateProperty<Output = bool>>> {
|
||||
match self {
|
||||
OperationTemplatePropertyKind::Core(property) => property.try_into_boolean(),
|
||||
|
@ -118,6 +118,9 @@ pub(crate) use {impl_core_wrap_property_fns, impl_wrap_property_fns};
|
||||
|
||||
/// Provides access to basic template property types.
|
||||
pub trait IntoTemplateProperty<'a> {
|
||||
/// Type name of the property output.
|
||||
fn type_name(&self) -> &'static str;
|
||||
|
||||
fn try_into_boolean(self) -> Option<Box<dyn TemplateProperty<Output = bool> + 'a>>;
|
||||
fn try_into_integer(self) -> Option<Box<dyn TemplateProperty<Output = i64> + 'a>>;
|
||||
|
||||
@ -149,6 +152,20 @@ pub enum CoreTemplatePropertyKind<'a> {
|
||||
}
|
||||
|
||||
impl<'a> IntoTemplateProperty<'a> for CoreTemplatePropertyKind<'a> {
|
||||
fn type_name(&self) -> &'static str {
|
||||
match self {
|
||||
CoreTemplatePropertyKind::String(_) => "String",
|
||||
CoreTemplatePropertyKind::StringList(_) => "List<String>",
|
||||
CoreTemplatePropertyKind::Boolean(_) => "Boolean",
|
||||
CoreTemplatePropertyKind::Integer(_) => "Integer",
|
||||
CoreTemplatePropertyKind::Signature(_) => "Signature",
|
||||
CoreTemplatePropertyKind::Timestamp(_) => "Timestamp",
|
||||
CoreTemplatePropertyKind::TimestampRange(_) => "TimestampRange",
|
||||
CoreTemplatePropertyKind::Template(_) => "Template",
|
||||
CoreTemplatePropertyKind::ListTemplate(_) => "ListTemplate",
|
||||
}
|
||||
}
|
||||
|
||||
fn try_into_boolean(self) -> Option<Box<dyn TemplateProperty<Output = bool> + 'a>> {
|
||||
match self {
|
||||
CoreTemplatePropertyKind::String(property) => {
|
||||
@ -317,10 +334,11 @@ impl<'a, L: TemplateLanguage<'a> + ?Sized> CoreTemplateBuildFnTable<'a, L> {
|
||||
property: CoreTemplatePropertyKind<'a>,
|
||||
function: &FunctionCallNode,
|
||||
) -> TemplateParseResult<L::Property> {
|
||||
let type_name = property.type_name();
|
||||
match property {
|
||||
CoreTemplatePropertyKind::String(property) => {
|
||||
let table = &self.string_methods;
|
||||
let build = template_parser::lookup_method("String", table, function)?;
|
||||
let build = template_parser::lookup_method(type_name, table, function)?;
|
||||
build(language, build_ctx, property, function)
|
||||
}
|
||||
CoreTemplatePropertyKind::StringList(property) => {
|
||||
@ -331,32 +349,32 @@ impl<'a, L: TemplateLanguage<'a> + ?Sized> CoreTemplateBuildFnTable<'a, L> {
|
||||
}
|
||||
CoreTemplatePropertyKind::Boolean(property) => {
|
||||
let table = &self.boolean_methods;
|
||||
let build = template_parser::lookup_method("Boolean", table, function)?;
|
||||
let build = template_parser::lookup_method(type_name, table, function)?;
|
||||
build(language, build_ctx, property, function)
|
||||
}
|
||||
CoreTemplatePropertyKind::Integer(property) => {
|
||||
let table = &self.integer_methods;
|
||||
let build = template_parser::lookup_method("Integer", table, function)?;
|
||||
let build = template_parser::lookup_method(type_name, table, function)?;
|
||||
build(language, build_ctx, property, function)
|
||||
}
|
||||
CoreTemplatePropertyKind::Signature(property) => {
|
||||
let table = &self.signature_methods;
|
||||
let build = template_parser::lookup_method("Signature", table, function)?;
|
||||
let build = template_parser::lookup_method(type_name, table, function)?;
|
||||
build(language, build_ctx, property, function)
|
||||
}
|
||||
CoreTemplatePropertyKind::Timestamp(property) => {
|
||||
let table = &self.timestamp_methods;
|
||||
let build = template_parser::lookup_method("Timestamp", table, function)?;
|
||||
let build = template_parser::lookup_method(type_name, table, function)?;
|
||||
build(language, build_ctx, property, function)
|
||||
}
|
||||
CoreTemplatePropertyKind::TimestampRange(property) => {
|
||||
let table = &self.timestamp_range_methods;
|
||||
let build = template_parser::lookup_method("TimestampRange", table, function)?;
|
||||
let build = template_parser::lookup_method(type_name, table, function)?;
|
||||
build(language, build_ctx, property, function)
|
||||
}
|
||||
CoreTemplatePropertyKind::Template(_) => {
|
||||
// TODO: migrate to table?
|
||||
Err(TemplateParseError::no_such_method("Template", function))
|
||||
Err(TemplateParseError::no_such_method(type_name, function))
|
||||
}
|
||||
CoreTemplatePropertyKind::ListTemplate(template) => {
|
||||
// TODO: migrate to table?
|
||||
@ -385,6 +403,10 @@ impl<P> Expression<P> {
|
||||
}
|
||||
|
||||
impl<'a, P: IntoTemplateProperty<'a>> Expression<P> {
|
||||
pub fn type_name(&self) -> &'static str {
|
||||
self.property.type_name()
|
||||
}
|
||||
|
||||
pub fn try_into_boolean(self) -> Option<Box<dyn TemplateProperty<Output = bool> + 'a>> {
|
||||
self.property.try_into_boolean()
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user