LCOV - code coverage report
Current view: top level - shumate/vector - shumate-vector-value.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 235 272 86.4 %
Date: 2024-05-11 21:41:31 Functions: 28 29 96.6 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 112 170 65.9 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (C) 2021 James Westman <james@jwestman.net>
       3                 :            :  *
       4                 :            :  * This library is free software; you can redistribute it and/or
       5                 :            :  * modify it under the terms of the GNU Lesser General Public
       6                 :            :  * License as published by the Free Software Foundation; either
       7                 :            :  * version 2.1 of the License, or (at your option) any later version.
       8                 :            :  *
       9                 :            :  * This library is distributed in the hope that it will be useful,
      10                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12                 :            :  * Lesser General Public License for more details.
      13                 :            :  *
      14                 :            :  * You should have received a copy of the GNU Lesser General Public
      15                 :            :  * License along with this library; if not, see <https://www.gnu.org/licenses/>.
      16                 :            :  */
      17                 :            : 
      18                 :            : #include "shumate-vector-renderer.h"
      19                 :            : #include "shumate-vector-value-private.h"
      20                 :            : 
      21                 :            : enum {
      22                 :            :   COLOR_UNSET,
      23                 :            :   COLOR_SET,
      24                 :            :   COLOR_INVALID,
      25                 :            : };
      26                 :            : 
      27                 :            : gboolean
      28                 :       1677 : shumate_vector_value_set_from_json_literal (ShumateVectorValue *self, JsonNode *node, GError **error)
      29                 :            : {
      30         [ +  + ]:       1677 :   if (JSON_NODE_HOLDS_NULL (node))
      31                 :            :     {
      32                 :          9 :       shumate_vector_value_unset (self);
      33                 :          9 :       return TRUE;
      34                 :            :     }
      35         [ +  + ]:       1668 :   else if (JSON_NODE_HOLDS_VALUE (node))
      36                 :            :     {
      37                 :       1557 :       g_auto(GValue) gvalue = G_VALUE_INIT;
      38                 :            : 
      39                 :       1557 :       json_node_get_value (node, &gvalue);
      40         [ -  + ]:       1557 :       if (!shumate_vector_value_set_from_g_value (self, &gvalue))
      41                 :            :         {
      42                 :          0 :           g_set_error (error,
      43                 :            :                       SHUMATE_STYLE_ERROR,
      44                 :            :                       SHUMATE_STYLE_ERROR_INVALID_EXPRESSION,
      45                 :            :                       "Unsupported literal value in expression");
      46                 :          0 :           return FALSE;
      47                 :            :         }
      48                 :            : 
      49                 :            :       return TRUE;
      50                 :            :     }
      51         [ +  - ]:        111 :   else if (JSON_NODE_HOLDS_ARRAY (node))
      52                 :            :     {
      53                 :        111 :       g_auto(ShumateVectorValue) value = SHUMATE_VECTOR_VALUE_INIT;
      54                 :        111 :       JsonArray *array = json_node_get_array (node);
      55                 :            : 
      56                 :        111 :       shumate_vector_value_start_array (self);
      57                 :            : 
      58         [ +  + ]:        378 :       for (int i = 0, n = json_array_get_length (array); i < n; i ++)
      59                 :            :         {
      60         [ +  - ]:        267 :           if (!shumate_vector_value_set_from_json_literal (&value, json_array_get_element (array, i), error))
      61                 :            :             return FALSE;
      62                 :            : 
      63                 :        267 :           shumate_vector_value_array_append (self, &value);
      64                 :            :         }
      65                 :            : 
      66                 :            :       return TRUE;
      67                 :            :     }
      68         [ #  # ]:          0 :   else if (JSON_NODE_HOLDS_OBJECT (node))
      69                 :            :     {
      70                 :          0 :       g_set_error (error,
      71                 :            :                    SHUMATE_STYLE_ERROR,
      72                 :            :                    SHUMATE_STYLE_ERROR_UNSUPPORTED,
      73                 :            :                    "Object literals are not supported");
      74                 :          0 :       return FALSE;
      75                 :            :     }
      76                 :            :   else
      77                 :            :     {
      78                 :          0 :       g_warn_if_reached ();
      79                 :          0 :       return FALSE;
      80                 :            :     }
      81                 :            : }
      82                 :            : 
      83                 :            : gboolean
      84                 :       1653 : shumate_vector_value_set_from_g_value (ShumateVectorValue *self, const GValue *value)
      85                 :            : {
      86                 :       3306 :   g_auto(GValue) tmp = G_VALUE_INIT;
      87                 :            : 
      88         [ -  + ]:       1653 :   if (value == NULL)
      89                 :          0 :     shumate_vector_value_unset (self);
      90         [ +  + ]:       1653 :   else if (g_value_type_transformable (G_VALUE_TYPE (value), G_TYPE_DOUBLE))
      91                 :            :     {
      92                 :        816 :       g_value_init (&tmp, G_TYPE_DOUBLE);
      93                 :        816 :       g_value_transform (value, &tmp);
      94                 :        816 :       shumate_vector_value_set_number (self, g_value_get_double (&tmp));
      95                 :            :     }
      96         [ +  + ]:        837 :   else if (g_value_type_transformable (G_VALUE_TYPE (value), G_TYPE_BOOLEAN))
      97                 :            :     {
      98                 :        144 :       g_value_init (&tmp, G_TYPE_BOOLEAN);
      99                 :        144 :       g_value_transform (value, &tmp);
     100                 :        144 :       shumate_vector_value_set_boolean (self, g_value_get_boolean (&tmp));
     101                 :            :     }
     102         [ +  - ]:        693 :   else if (g_value_type_transformable (G_VALUE_TYPE (value), G_TYPE_STRING))
     103                 :            :     {
     104                 :        693 :       g_value_init (&tmp, G_TYPE_STRING);
     105                 :        693 :       g_value_transform (value, &tmp);
     106                 :        693 :       shumate_vector_value_set_string (self, g_value_get_string (&tmp));
     107                 :            :     }
     108                 :            :   else
     109                 :            :     return FALSE;
     110                 :            : 
     111                 :            :   return TRUE;
     112                 :            : }
     113                 :            : 
     114                 :            : 
     115                 :            : void
     116                 :        396 : shumate_vector_value_free (ShumateVectorValue *self)
     117                 :            : {
     118                 :        396 :   shumate_vector_value_unset (self);
     119                 :        396 :   g_free (self);
     120                 :        396 : }
     121                 :            : 
     122                 :            : 
     123                 :            : void
     124                 :      20499 : shumate_vector_value_unset (ShumateVectorValue *self)
     125                 :            : {
     126   [ +  +  +  +  :      20499 :   switch (self->type)
                      + ]
     127                 :            :     {
     128                 :       2181 :     case SHUMATE_VECTOR_VALUE_TYPE_STRING:
     129         [ +  - ]:       2181 :       g_clear_pointer (&self->string, g_free);
     130                 :            :       break;
     131                 :        360 :     case SHUMATE_VECTOR_VALUE_TYPE_ARRAY:
     132         [ +  - ]:        360 :       g_clear_pointer (&self->array, g_ptr_array_unref);
     133                 :            :       break;
     134                 :          3 :     case SHUMATE_VECTOR_VALUE_TYPE_RESOLVED_IMAGE:
     135         [ +  - ]:          3 :       g_clear_object (&self->image);
     136         [ +  - ]:          3 :       g_clear_pointer (&self->image_name, g_free);
     137                 :            :       break;
     138                 :          3 :     case SHUMATE_VECTOR_VALUE_TYPE_FORMATTED_STRING:
     139         [ +  - ]:          3 :       g_clear_pointer (&self->formatted_string, g_ptr_array_unref);
     140                 :            :       break;
     141                 :            :     case SHUMATE_VECTOR_VALUE_TYPE_NULL:
     142                 :            :     case SHUMATE_VECTOR_VALUE_TYPE_NUMBER:
     143                 :            :     case SHUMATE_VECTOR_VALUE_TYPE_BOOLEAN:
     144                 :            :     case SHUMATE_VECTOR_VALUE_TYPE_COLOR:
     145                 :            :     case SHUMATE_VECTOR_VALUE_TYPE_COLLATOR:
     146                 :            :       break;
     147                 :            :     }
     148                 :            : 
     149                 :      20499 :   self->type = SHUMATE_VECTOR_VALUE_TYPE_NULL;
     150                 :      20499 : }
     151                 :            : 
     152                 :            : 
     153                 :            : gboolean
     154                 :         51 : shumate_vector_value_is_null (ShumateVectorValue *self)
     155                 :            : {
     156                 :         51 :   return self->type == SHUMATE_VECTOR_VALUE_TYPE_NULL;
     157                 :            : }
     158                 :            : 
     159                 :            : 
     160                 :            : void
     161                 :       3900 : shumate_vector_value_copy (ShumateVectorValue *self, ShumateVectorValue *out)
     162                 :            : {
     163                 :       3900 :   shumate_vector_value_unset (out);
     164                 :       3900 :   *out = *self;
     165                 :            : 
     166   [ +  +  -  -  :       3900 :   switch (self->type)
                      + ]
     167                 :            :     {
     168                 :       1260 :     case SHUMATE_VECTOR_VALUE_TYPE_STRING:
     169         [ -  + ]:       1260 :       out->string = g_strdup (self->string);
     170                 :       1260 :       break;
     171                 :        213 :     case SHUMATE_VECTOR_VALUE_TYPE_ARRAY:
     172                 :        213 :       out->array = g_ptr_array_ref (self->array);
     173                 :        213 :       break;
     174                 :          0 :     case SHUMATE_VECTOR_VALUE_TYPE_RESOLVED_IMAGE:
     175                 :          0 :       out->image = g_object_ref (self->image);
     176         [ #  # ]:          0 :       out->image_name = g_strdup (self->image_name);
     177                 :          0 :       break;
     178                 :          0 :     case SHUMATE_VECTOR_VALUE_TYPE_FORMATTED_STRING:
     179                 :          0 :       out->formatted_string = g_ptr_array_ref (self->formatted_string);
     180                 :          0 :       break;
     181                 :            :     case SHUMATE_VECTOR_VALUE_TYPE_NULL:
     182                 :            :     case SHUMATE_VECTOR_VALUE_TYPE_NUMBER:
     183                 :            :     case SHUMATE_VECTOR_VALUE_TYPE_BOOLEAN:
     184                 :            :     case SHUMATE_VECTOR_VALUE_TYPE_COLOR:
     185                 :            :     case SHUMATE_VECTOR_VALUE_TYPE_COLLATOR:
     186                 :            :       break;
     187                 :            :     }
     188                 :       3900 : }
     189                 :            : 
     190                 :            : void
     191                 :          9 : shumate_vector_value_steal (ShumateVectorValue *self, ShumateVectorValue *out)
     192                 :            : {
     193                 :          9 :   *out = *self;
     194                 :          9 :   self->type = SHUMATE_VECTOR_VALUE_TYPE_NULL;
     195                 :          9 : }
     196                 :            : 
     197                 :            : 
     198                 :            : void
     199                 :       1101 : shumate_vector_value_set_number (ShumateVectorValue *self, double number)
     200                 :            : {
     201                 :       1101 :   shumate_vector_value_unset (self);
     202                 :       1101 :   self->type = SHUMATE_VECTOR_VALUE_TYPE_NUMBER;
     203                 :       1101 :   self->number = number;
     204                 :       1101 : }
     205                 :            : 
     206                 :            : 
     207                 :            : gboolean
     208                 :        852 : shumate_vector_value_get_number (ShumateVectorValue *self, double *number)
     209                 :            : {
     210         [ +  + ]:        852 :   if (self->type != SHUMATE_VECTOR_VALUE_TYPE_NUMBER)
     211                 :            :     return FALSE;
     212                 :            : 
     213                 :        627 :   *number = self->number;
     214                 :        627 :   return TRUE;
     215                 :            : }
     216                 :            : 
     217                 :            : 
     218                 :            : void
     219                 :        723 : shumate_vector_value_set_boolean (ShumateVectorValue *self, gboolean boolean)
     220                 :            : {
     221                 :        723 :   shumate_vector_value_unset (self);
     222                 :        723 :   self->type = SHUMATE_VECTOR_VALUE_TYPE_BOOLEAN;
     223                 :        723 :   self->boolean = boolean;
     224                 :        723 : }
     225                 :            : 
     226                 :            : 
     227                 :            : gboolean
     228                 :        741 : shumate_vector_value_get_boolean (ShumateVectorValue *self, gboolean *boolean)
     229                 :            : {
     230         [ +  + ]:        741 :   if (self->type != SHUMATE_VECTOR_VALUE_TYPE_BOOLEAN)
     231                 :            :     return FALSE;
     232                 :            : 
     233                 :        618 :   *boolean = self->boolean;
     234                 :        618 :   return TRUE;
     235                 :            : }
     236                 :            : 
     237                 :            : 
     238                 :            : void
     239                 :        921 : shumate_vector_value_set_string (ShumateVectorValue *self, const char *string)
     240                 :            : {
     241                 :        921 :   shumate_vector_value_unset (self);
     242                 :        921 :   self->type = SHUMATE_VECTOR_VALUE_TYPE_STRING;
     243         [ -  + ]:        921 :   self->string = g_strdup (string);
     244                 :        921 :   self->color_state = COLOR_UNSET;
     245                 :        921 : }
     246                 :            : 
     247                 :            : 
     248                 :            : gboolean
     249                 :        411 : shumate_vector_value_get_string (ShumateVectorValue *self, const char **string)
     250                 :            : {
     251         [ +  + ]:        411 :   if (self->type != SHUMATE_VECTOR_VALUE_TYPE_STRING)
     252                 :            :     return FALSE;
     253                 :            : 
     254                 :        234 :   *string = self->string;
     255                 :        234 :   return TRUE;
     256                 :            : }
     257                 :            : 
     258                 :            : 
     259                 :            : void
     260                 :         45 : shumate_vector_value_set_color (ShumateVectorValue *self, GdkRGBA *color)
     261                 :            : {
     262                 :         45 :   shumate_vector_value_unset (self);
     263                 :         45 :   self->type = SHUMATE_VECTOR_VALUE_TYPE_COLOR;
     264                 :         45 :   self->color = *color;
     265                 :         45 : }
     266                 :            : 
     267                 :            : 
     268                 :            : gboolean
     269                 :        123 : shumate_vector_value_get_color (ShumateVectorValue *self, GdkRGBA *color)
     270                 :            : {
     271         [ +  + ]:        123 :   if (self->type == SHUMATE_VECTOR_VALUE_TYPE_STRING)
     272                 :            :     {
     273         [ +  + ]:         81 :       if (self->color_state == COLOR_UNSET)
     274                 :            :         {
     275         [ +  + ]:         75 :           if (gdk_rgba_parse (&self->color, self->string))
     276                 :         69 :             self->color_state = COLOR_SET;
     277                 :            :           else
     278                 :          6 :             self->color_state = COLOR_INVALID;
     279                 :            :         }
     280                 :            : 
     281         [ +  + ]:         81 :       if (self->color_state == COLOR_SET)
     282                 :            :         {
     283                 :         72 :           *color = self->color;
     284                 :         72 :           return TRUE;
     285                 :            :         }
     286                 :            :       else
     287                 :            :         return FALSE;
     288                 :            :     }
     289                 :            : 
     290         [ +  + ]:         42 :   if (self->type != SHUMATE_VECTOR_VALUE_TYPE_COLOR)
     291                 :            :     return FALSE;
     292                 :            : 
     293                 :         12 :   *color = self->color;
     294                 :         12 :   return TRUE;
     295                 :            : }
     296                 :            : 
     297                 :            : 
     298                 :            : void
     299                 :        147 : shumate_vector_value_start_array (ShumateVectorValue *self)
     300                 :            : {
     301                 :        147 :   shumate_vector_value_unset (self);
     302                 :        147 :   self->type = SHUMATE_VECTOR_VALUE_TYPE_ARRAY;
     303                 :        147 :   self->array = g_ptr_array_new_with_free_func ((GDestroyNotify)shumate_vector_value_free);
     304                 :        147 : }
     305                 :            : 
     306                 :            : 
     307                 :            : void
     308                 :        336 : shumate_vector_value_array_append (ShumateVectorValue *self, ShumateVectorValue *element)
     309                 :            : {
     310                 :        672 :   g_autoptr(ShumateVectorValue) copy = g_new0 (ShumateVectorValue, 1);
     311                 :            : 
     312   [ +  -  -  - ]:        336 :   g_return_if_fail (self->type == SHUMATE_VECTOR_VALUE_TYPE_ARRAY);
     313                 :            : 
     314                 :        336 :   shumate_vector_value_copy (element, copy);
     315                 :        336 :   g_ptr_array_add (self->array, g_steal_pointer (&copy));
     316                 :            : }
     317                 :            : 
     318                 :            : 
     319                 :            : GPtrArray *
     320                 :         63 : shumate_vector_value_get_array (ShumateVectorValue *self)
     321                 :            : {
     322         [ +  + ]:         63 :   if (self->type != SHUMATE_VECTOR_VALUE_TYPE_ARRAY)
     323                 :            :     return NULL;
     324                 :            : 
     325                 :         48 :   return self->array;
     326                 :            : }
     327                 :            : 
     328                 :            : 
     329                 :            : void
     330                 :          3 : shumate_vector_value_set_image (ShumateVectorValue  *self,
     331                 :            :                                 ShumateVectorSprite *image,
     332                 :            :                                 const char          *image_name)
     333                 :            : {
     334         [ +  - ]:          3 :   g_assert (SHUMATE_IS_VECTOR_SPRITE (image));
     335         [ -  + ]:          3 :   g_assert (image_name != NULL);
     336                 :            : 
     337                 :          3 :   shumate_vector_value_unset (self);
     338                 :          3 :   self->type = SHUMATE_VECTOR_VALUE_TYPE_RESOLVED_IMAGE;
     339                 :          3 :   self->image = g_object_ref (image);
     340         [ -  + ]:          3 :   self->image_name = g_strdup (image_name);
     341                 :          3 : }
     342                 :            : 
     343                 :            : gboolean
     344                 :          0 : shumate_vector_value_get_image (ShumateVectorValue *self, ShumateVectorSprite **image)
     345                 :            : {
     346         [ #  # ]:          0 :   if (self->type != SHUMATE_VECTOR_VALUE_TYPE_RESOLVED_IMAGE)
     347                 :            :     return FALSE;
     348                 :            : 
     349                 :          0 :   *image = self->image;
     350                 :          0 :   return TRUE;
     351                 :            : }
     352                 :            : 
     353                 :            : void
     354                 :          3 : shumate_vector_value_set_formatted (ShumateVectorValue *self,
     355                 :            :                                     GPtrArray          *format_parts)
     356                 :            : {
     357                 :          3 :   shumate_vector_value_unset (self);
     358                 :          3 :   self->type = SHUMATE_VECTOR_VALUE_TYPE_FORMATTED_STRING;
     359                 :          3 :   self->formatted_string = g_ptr_array_ref (format_parts);
     360                 :          3 : }
     361                 :            : 
     362                 :            : gboolean
     363                 :          3 : shumate_vector_value_get_formatted (ShumateVectorValue  *self,
     364                 :            :                                     GPtrArray          **format_parts)
     365                 :            : {
     366         [ +  - ]:          3 :   if (self->type != SHUMATE_VECTOR_VALUE_TYPE_FORMATTED_STRING)
     367                 :            :     return FALSE;
     368                 :            : 
     369                 :          3 :   *format_parts = self->formatted_string;
     370                 :          3 :   return TRUE;
     371                 :            : }
     372                 :            : 
     373                 :            : void
     374                 :         30 : shumate_vector_format_part_free (ShumateVectorFormatPart *format_part)
     375                 :            : {
     376         [ +  + ]:         30 :   g_clear_pointer (&format_part->string, g_free);
     377         [ -  + ]:         30 :   g_clear_object (&format_part->sprite);
     378                 :         30 :   g_free (format_part);
     379                 :         30 : }
     380                 :            : 
     381                 :            : void
     382                 :         18 : shumate_vector_value_set_collator (ShumateVectorValue    *self,
     383                 :            :                                    ShumateVectorCollator *collator)
     384                 :            : {
     385                 :         18 :   shumate_vector_value_unset (self);
     386                 :         18 :   self->type = SHUMATE_VECTOR_VALUE_TYPE_COLLATOR;
     387                 :         18 :   self->collator = *collator;
     388                 :         18 : }
     389                 :            : 
     390                 :            : gboolean
     391                 :         15 : shumate_vector_value_get_collator (ShumateVectorValue    *self,
     392                 :            :                                    ShumateVectorCollator *collator)
     393                 :            : {
     394         [ +  - ]:         15 :   if (self->type != SHUMATE_VECTOR_VALUE_TYPE_COLLATOR)
     395                 :            :     return FALSE;
     396                 :            : 
     397                 :         15 :   *collator = self->collator;
     398                 :         15 :   return TRUE;
     399                 :            : }
     400                 :            : 
     401                 :            : gint
     402                 :         96 : shumate_vector_value_hash (ShumateVectorValue *self)
     403                 :            : {
     404   [ +  +  +  -  :         96 :   switch (self->type)
             -  -  -  - ]
     405                 :            :     {
     406                 :            :     case SHUMATE_VECTOR_VALUE_TYPE_NULL:
     407                 :            :       return 0;
     408                 :         24 :     case SHUMATE_VECTOR_VALUE_TYPE_NUMBER:
     409                 :         24 :       return g_double_hash (&self->number);
     410                 :          6 :     case SHUMATE_VECTOR_VALUE_TYPE_BOOLEAN:
     411                 :          6 :       return !!self->boolean;
     412                 :         66 :     case SHUMATE_VECTOR_VALUE_TYPE_STRING:
     413                 :         66 :       return g_str_hash (self->string);
     414                 :          0 :     case SHUMATE_VECTOR_VALUE_TYPE_COLOR:
     415                 :          0 :       return gdk_rgba_hash (&self->color);
     416                 :            :     case SHUMATE_VECTOR_VALUE_TYPE_ARRAY:
     417                 :            :       {
     418                 :            :         guint hash = 0;
     419                 :            : 
     420         [ #  # ]:          0 :         for (int i = 0; i < self->array->len; i ++)
     421                 :          0 :           hash ^= shumate_vector_value_hash (g_ptr_array_index (self->array, i));
     422                 :            : 
     423                 :          0 :         return hash;
     424                 :            :       }
     425                 :          0 :     case SHUMATE_VECTOR_VALUE_TYPE_RESOLVED_IMAGE:
     426                 :          0 :       return g_str_hash (self->image_name);
     427                 :            :     case SHUMATE_VECTOR_VALUE_TYPE_FORMATTED_STRING:
     428                 :            :     case SHUMATE_VECTOR_VALUE_TYPE_COLLATOR:
     429                 :            :       /* Not supported */
     430                 :            :       return 0;
     431                 :          0 :     default:
     432                 :          0 :       g_assert_not_reached ();
     433                 :            :     }
     434                 :            : }
     435                 :            : 
     436                 :            : gboolean
     437                 :        555 : shumate_vector_value_equal (ShumateVectorValue *a, ShumateVectorValue *b)
     438                 :            : {
     439         [ +  + ]:        555 :   if (a->type != b->type)
     440                 :            :     return FALSE;
     441                 :            : 
     442   [ +  +  +  +  :        531 :   switch (a->type)
             +  +  -  -  
                      - ]
     443                 :            :     {
     444                 :            :     case SHUMATE_VECTOR_VALUE_TYPE_NULL:
     445                 :            :       return TRUE;
     446                 :        210 :     case SHUMATE_VECTOR_VALUE_TYPE_NUMBER:
     447                 :        210 :       return a->number == b->number;
     448                 :         39 :     case SHUMATE_VECTOR_VALUE_TYPE_BOOLEAN:
     449                 :         39 :       return a->boolean == b->boolean;
     450                 :        207 :     case SHUMATE_VECTOR_VALUE_TYPE_STRING:
     451                 :        207 :       return g_strcmp0 (a->string, b->string) == 0;
     452                 :         15 :     case SHUMATE_VECTOR_VALUE_TYPE_COLOR:
     453                 :         15 :       return gdk_rgba_equal (&a->color, &b->color);
     454                 :         42 :     case SHUMATE_VECTOR_VALUE_TYPE_ARRAY:
     455         [ +  + ]:         42 :       if (a->array->len != b->array->len)
     456                 :            :         return FALSE;
     457                 :            : 
     458         [ +  + ]:        105 :       for (int i = 0; i < a->array->len; i ++)
     459         [ +  - ]:         66 :         if (!shumate_vector_value_equal (g_ptr_array_index (a->array, i), g_ptr_array_index (b->array, i)))
     460                 :            :           return FALSE;
     461                 :            : 
     462                 :            :       return TRUE;
     463                 :          0 :     case SHUMATE_VECTOR_VALUE_TYPE_RESOLVED_IMAGE:
     464                 :          0 :       return g_strcmp0 (a->image_name, b->image_name) == 0;
     465                 :            :     case SHUMATE_VECTOR_VALUE_TYPE_FORMATTED_STRING:
     466                 :            :     case SHUMATE_VECTOR_VALUE_TYPE_COLLATOR:
     467                 :            :       /* Not supported */
     468                 :            :       return FALSE;
     469                 :          0 :     default:
     470                 :          0 :       g_assert_not_reached ();
     471                 :            :     }
     472                 :            : }
     473                 :            : 
     474                 :            : 
     475                 :            : static JsonNode *
     476                 :         30 : shumate_vector_value_as_json (ShumateVectorValue *value)
     477                 :            : {
     478                 :         30 :   JsonNode *node;
     479                 :            : 
     480   [ +  +  +  +  :         30 :   switch (value->type)
                      + ]
     481                 :            :     {
     482                 :          3 :     case SHUMATE_VECTOR_VALUE_TYPE_NULL:
     483                 :          3 :       node = json_node_new (JSON_NODE_NULL);
     484                 :          3 :       return node;
     485                 :          6 :     case SHUMATE_VECTOR_VALUE_TYPE_NUMBER:
     486                 :          6 :       node = json_node_new (JSON_NODE_VALUE);
     487         [ +  + ]:          6 :       if (fmod (value->number, 1) == 0)
     488                 :          3 :         json_node_set_int (node, value->number);
     489                 :            :       else
     490                 :          3 :         json_node_set_double (node, value->number);
     491                 :            :       return node;
     492                 :          6 :     case SHUMATE_VECTOR_VALUE_TYPE_BOOLEAN:
     493                 :          6 :       node = json_node_new (JSON_NODE_VALUE);
     494                 :          6 :       json_node_set_boolean (node, value->boolean);
     495                 :          6 :       return node;
     496                 :          9 :     case SHUMATE_VECTOR_VALUE_TYPE_ARRAY:
     497                 :            :       {
     498                 :          9 :         g_autoptr(JsonBuilder) builder = json_builder_new ();
     499                 :          9 :         json_builder_begin_array (builder);
     500         [ +  + ]:         33 :         for (int i = 0; i < value->array->len; i ++)
     501                 :            :           {
     502                 :         24 :             ShumateVectorValue *child = g_ptr_array_index (value->array, i);
     503                 :         24 :             json_builder_add_value (builder, shumate_vector_value_as_json (child));
     504                 :            :           }
     505                 :            : 
     506                 :          9 :         json_builder_end_array (builder);
     507         [ +  - ]:          9 :         return json_builder_get_root (builder);
     508                 :            :       }
     509                 :          6 :     default:
     510                 :            :       {
     511                 :         12 :         g_autofree char *string = shumate_vector_value_as_string (value);
     512                 :          6 :         node = json_node_new (JSON_NODE_VALUE);
     513                 :          6 :         json_node_set_string (node, string);
     514                 :          6 :         return node;
     515                 :            :       }
     516                 :            :     }
     517                 :            : }
     518                 :            : 
     519                 :            : 
     520                 :            : char *
     521                 :        123 : shumate_vector_value_as_string (ShumateVectorValue *self)
     522                 :            : {
     523   [ +  +  +  +  :        123 :   switch (self->type)
          +  +  -  +  -  
                      - ]
     524                 :            :     {
     525                 :            :     case SHUMATE_VECTOR_VALUE_TYPE_NULL:
     526                 :          3 :       return g_strdup ("");
     527                 :         24 :     case SHUMATE_VECTOR_VALUE_TYPE_NUMBER:
     528                 :            :       /* printf produces nan, inf, and -inf, but the spec says we should act like ECMAScript
     529                 :            :          which uses NaN, -Infinity, and Infinity */
     530         [ +  + ]:         24 :       if (G_UNLIKELY (isnan (self->number)))
     531                 :         12 :         return g_strdup ("NaN");
     532         [ +  + ]:         12 :       else if (G_UNLIKELY (isinf (self->number)))
     533                 :            :         {
     534         [ +  + ]:          6 :           if (self->number < 0)
     535                 :          3 :             return g_strdup ("-Infinity");
     536                 :            :           else
     537                 :          3 :             return g_strdup ("Infinity");
     538                 :            :         }
     539                 :            :       else
     540                 :          6 :         return g_strdup_printf ("%g", self->number);
     541                 :          9 :     case SHUMATE_VECTOR_VALUE_TYPE_BOOLEAN:
     542         [ +  + ]:          9 :       return g_strdup (self->boolean ? "true" : "false");
     543                 :         72 :     case SHUMATE_VECTOR_VALUE_TYPE_STRING:
     544         [ -  + ]:         72 :       return g_strdup (self->string);
     545                 :          6 :     case SHUMATE_VECTOR_VALUE_TYPE_COLOR:
     546                 :            :       /* gdk_rgba_to_string() produces `rgb(...)` when alpha is ~1, which is
     547                 :            :          not consistent with the MapLibre spec */
     548                 :         24 :       return g_strdup_printf (
     549                 :            :         "rgba(%d,%d,%d,%g)",
     550         [ +  - ]:         12 :         (int)round (255 * CLAMP (self->color.red, 0, 1)),
     551   [ +  -  +  - ]:         12 :         (int)round (255 * CLAMP (self->color.green, 0, 1)),
     552   [ +  -  +  -  :         12 :         (int)round (255 * CLAMP (self->color.blue, 0, 1)),
                   +  - ]
     553   [ +  -  +  - ]:          6 :         CLAMP (self->color.alpha, 0, 1)
     554                 :            :       );
     555                 :          6 :     case SHUMATE_VECTOR_VALUE_TYPE_ARRAY:
     556                 :            :       {
     557                 :          6 :         g_autoptr(JsonNode) node = shumate_vector_value_as_json (self);
     558         [ +  - ]:          6 :         return json_to_string (node, FALSE);
     559                 :            :       }
     560                 :          0 :     case SHUMATE_VECTOR_VALUE_TYPE_RESOLVED_IMAGE:
     561         [ #  # ]:          0 :       return g_strdup (self->image_name);
     562                 :          3 :     case SHUMATE_VECTOR_VALUE_TYPE_FORMATTED_STRING:
     563                 :            :       {
     564                 :          6 :         g_autoptr(GString) result = g_string_new ("");
     565                 :            : 
     566         [ +  + ]:         15 :         for (int i = 0; i < self->formatted_string->len; i ++)
     567                 :            :           {
     568                 :         12 :             ShumateVectorFormatPart *part = g_ptr_array_index (self->formatted_string, i);
     569         [ +  - ]:         12 :             if (!part->sprite)
     570         [ -  + ]:         24 :               g_string_append (result, part->string);
     571                 :            :           }
     572                 :            : 
     573                 :          3 :         return g_string_free (g_steal_pointer (&result), FALSE);
     574                 :            :       }
     575                 :            :     case SHUMATE_VECTOR_VALUE_TYPE_COLLATOR:
     576                 :            :       /* Not supported */
     577                 :          0 :       return g_strdup ("");
     578                 :          0 :     default:
     579                 :          0 :       g_assert_not_reached ();
     580                 :            :     }
     581                 :            : }

Generated by: LCOV version 1.14