comparison mercurial/templateutil.py @ 38296:e72697893c93

templater: promote tomap() to an interface type I originally considered merging tomap() with itermaps()/getmember(), but decided to not. We might want to add support for chained map operations (e.g. {foo % func() % ...}), where func() will return a mappable object, and 'foo % func()' will be a mappedgenerator of mappable objects.
author Yuya Nishihara <yuya@tcha.org>
date Sat, 21 Apr 2018 19:01:35 +0900
parents 0e0d03d09ecd
children 8d6109b49b31
comparison
equal deleted inserted replaced
38295:0e0d03d09ecd 38296:e72697893c93
89 """Move the inner value object out or create a value representation 89 """Move the inner value object out or create a value representation
90 90
91 A returned value must be serializable by templaterfilters.json(). 91 A returned value must be serializable by templaterfilters.json().
92 """ 92 """
93 93
94 class mappable(object):
95 """Object which can be converted to a single template mapping"""
96
97 def itermaps(self, context):
98 yield self.tomap(context)
99
100 @abc.abstractmethod
101 def tomap(self, context):
102 """Create a single template mapping representing this"""
103
94 class wrappedbytes(wrapped): 104 class wrappedbytes(wrapped):
95 """Wrapper for byte string""" 105 """Wrapper for byte string"""
96 106
97 def __init__(self, value): 107 def __init__(self, value):
98 self._value = value 108 self._value = value
241 if util.safehasattr(xs, 'get'): 251 if util.safehasattr(xs, 'get'):
242 return {k: unwrapvalue(context, mapping, v) 252 return {k: unwrapvalue(context, mapping, v)
243 for k, v in xs.iteritems()} 253 for k, v in xs.iteritems()}
244 return [unwrapvalue(context, mapping, x) for x in xs] 254 return [unwrapvalue(context, mapping, x) for x in xs]
245 255
246 class hybriditem(wrapped): 256 class hybriditem(mappable, wrapped):
247 """Wrapper for non-list/dict object to support map operation 257 """Wrapper for non-list/dict object to support map operation
248 258
249 This class allows us to handle both: 259 This class allows us to handle both:
250 - "{manifest}" 260 - "{manifest}"
251 - "{manifest % '{rev}:{node}'}" 261 - "{manifest % '{rev}:{node}'}"
256 self._gen = gen # generator or function returning generator 266 self._gen = gen # generator or function returning generator
257 self._key = key 267 self._key = key
258 self._value = value # may be generator of strings 268 self._value = value # may be generator of strings
259 self._makemap = makemap 269 self._makemap = makemap
260 270
261 def tomap(self): 271 def tomap(self, context):
262 return self._makemap(self._key) 272 return self._makemap(self._key)
263 273
264 def contains(self, context, mapping, item): 274 def contains(self, context, mapping, item):
265 w = makewrapped(context, mapping, self._value) 275 w = makewrapped(context, mapping, self._value)
266 return w.contains(context, mapping, item) 276 return w.contains(context, mapping, item)
274 return w.getmin(context, mapping) 284 return w.getmin(context, mapping)
275 285
276 def getmax(self, context, mapping): 286 def getmax(self, context, mapping):
277 w = makewrapped(context, mapping, self._value) 287 w = makewrapped(context, mapping, self._value)
278 return w.getmax(context, mapping) 288 return w.getmax(context, mapping)
279
280 def itermaps(self, context):
281 yield self.tomap()
282 289
283 def join(self, context, mapping, sep): 290 def join(self, context, mapping, sep):
284 w = makewrapped(context, mapping, self._value) 291 w = makewrapped(context, mapping, self._value)
285 return w.join(context, mapping, sep) 292 return w.join(context, mapping, sep)
286 293
773 return mappedgenerator(_applymap, args=(mapping, d, darg, targ)) 780 return mappedgenerator(_applymap, args=(mapping, d, darg, targ))
774 781
775 def runmember(context, mapping, data): 782 def runmember(context, mapping, data):
776 darg, memb = data 783 darg, memb = data
777 d = evalwrapped(context, mapping, darg) 784 d = evalwrapped(context, mapping, darg)
778 if util.safehasattr(d, 'tomap'): 785 if isinstance(d, mappable):
779 lm = context.overlaymap(mapping, d.tomap()) 786 lm = context.overlaymap(mapping, d.tomap(context))
780 return runsymbol(context, lm, memb) 787 return runsymbol(context, lm, memb)
781 try: 788 try:
782 return d.getmember(context, mapping, memb) 789 return d.getmember(context, mapping, memb)
783 except error.ParseError as err: 790 except error.ParseError as err:
784 sym = findsymbolicname(darg) 791 sym = findsymbolicname(darg)