blob: fb2516b84bfdf8952e7f258ad1a78444ebb6d3b2 [file] [log] [blame]
# Copyright 2024 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""Utilities for handling singular/plural forms in logs and tooling."""
def plural(
items_or_count,
singular: str,
count_format='',
these: bool = False,
number: bool = True,
are: bool = False,
exist: bool = False,
) -> str:
"""Returns the singular or plural form of a word based on a count.
Args:
items_or_count: Number of items or a collection of items
singular: Singular form of the name of the item
count_format: .format()-style specification for items_or_count
these: Prefix the string with "this" or "these", depending on number
number: Include the number in the return string (e.g., "3 things" vs.
"things")
are: Suffix the string with "is" or "are", depending on number
exist: Suffix the string with "exists" or "exist", depending on number
"""
try:
count = len(items_or_count)
except TypeError:
count = items_or_count
prefix = ('this ' if count == 1 else 'these ') if these else ''
num = f'{count:{count_format}} ' if number else ''
suffix = ''
if are and exist:
raise ValueError(f'cannot combine are ({are}) and exist ({exist})')
if are:
suffix = ' is' if count == 1 else ' are'
if exist:
suffix = ' exists' if count == 1 else ' exist'
if singular.endswith('y'):
result = f'{singular[:-1]}{"y" if count == 1 else "ies"}'
elif singular.endswith('s'):
result = f'{singular}{"" if count == 1 else "es"}'
else:
result = f'{singular}{"" if count == 1 else "s"}'
return f'{prefix}{num}{result}{suffix}'