< Summary

Class:Willykc.Templ.Editor.Scaffold.TemplScaffoldYamlSerializer
Assembly:Willykc.Templ.Editor
File(s):/github/workspace/Packages/package.to.test/Editor/Scaffold/TemplScaffoldYamlSerializer.cs
Covered lines:73
Uncovered lines:2
Coverable lines:75
Total lines:175
Line coverage:97.3% (73 of 75)
Covered branches:0
Total branches:0
Covered methods:9
Total methods:9
Method coverage:100% (9 of 9)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
TemplScaffoldYamlSerializer()0%110100%
SerializeTree(...)0%220100%
DeserializeTree(...)0%220100%
BuildDtoTree(...)0%440100%
GetTemplateReference(...)0%330100%
ReadDtoTree(...)0%6.036090.48%
GetNode(...)0%440100%
GetDirectoryNode(...)0%110100%
GetFileNode(...)0%550100%

File(s)

/github/workspace/Packages/package.to.test/Editor/Scaffold/TemplScaffoldYamlSerializer.cs

#LineLine coverage
 1/*
 2 * Copyright (c) 2024 Willy Alberto Kuster
 3 *
 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
 5 * of this software and associated documentation files (the "Software"), to deal
 6 * in the Software without restriction, including without limitation the rights
 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 8 * copies of the Software, and to permit persons to whom the Software is
 9 * furnished to do so, subject to the following conditions:
 10 *
 11 * The above copyright notice and this permission notice shall be included in
 12 * all copies or substantial portions of the Software.
 13 *
 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 20 * THE SOFTWARE.
 21 */
 22using SharpYaml.Serialization;
 23using System;
 24using System.Collections.Generic;
 25using System.IO;
 26using System.Linq;
 27using UnityEditor;
 28
 29namespace Willykc.Templ.Editor.Scaffold
 30{
 31    internal static class TemplScaffoldYamlSerializer
 32    {
 33        private static readonly Serializer YamlSerializer;
 34
 35        static TemplScaffoldYamlSerializer()
 136        {
 137            var settings = new SerializerSettings()
 38            {
 39                EmitAlias = false,
 40                ComparerForKeySorting = null
 41            };
 42
 143            YamlSerializer = new Serializer(settings);
 144        }
 45
 46        internal static string SerializeTree(TemplScaffoldRoot root, bool useGuids = false)
 247        {
 248            root = root ?? throw new ArgumentNullException(nameof(root));
 49
 250            var dtoTree = BuildDtoTree(root, useGuids);
 51
 252            return YamlSerializer.Serialize(dtoTree);
 253        }
 54
 55        internal static TemplScaffoldRoot DeserializeTree(string fromText)
 1456        {
 1457            fromText = !string.IsNullOrWhiteSpace(fromText)
 58                ? fromText
 59                : throw new ArgumentException($"{nameof(fromText)} must not be null or empty");
 60
 1461            var dtoTree = YamlSerializer.Deserialize(fromText);
 1362            var children = ReadDtoTree(dtoTree);
 963            var root = new TemplScaffoldRoot() { name = nameof(TemplScaffold.Root) };
 964            root.AddChildrenRange(children);
 65
 966            return root;
 967        }
 68
 69        private static List<object> BuildDtoTree(TemplScaffoldNode node, bool useGuids)
 470        {
 471            var childrenList = new List<object>();
 72
 2073            foreach (var child in node.Children)
 474            {
 475                var childDto = new Dictionary<string, object>();
 76
 477                var value = child is TemplScaffoldFile file
 78                    ? GetTemplateReference(file, useGuids)
 79                    : BuildDtoTree(child, useGuids);
 80
 481                childDto.Add(child.name, value);
 82
 483                childrenList.Add(childDto);
 484            }
 85
 486            return childrenList;
 487        }
 88
 89        private static object GetTemplateReference(TemplScaffoldFile file, bool useGuids)
 290        {
 291            var path = AssetDatabase.GetAssetPath(file.Template);
 292            return useGuids
 93                ? AssetDatabase.AssetPathToGUID(path)
 94                : path;
 295        }
 96
 97        private static List<TemplScaffoldNode> ReadDtoTree(object dtoTree)
 3898        {
 3899            var childrenList = new List<TemplScaffoldNode>();
 100
 38101            if (!(dtoTree is IEnumerable<object> nodeEnumerable))
 1102            {
 1103                throw new InvalidOperationException(
 104                    "Serialized Scaffold tree nodes must always be collections");
 105            }
 106
 206107            foreach (var child in nodeEnumerable)
 50108            {
 50109                if (!(child is IDictionary<object, object> childDictionary))
 1110                {
 1111                    throw new InvalidOperationException(
 112                        "Serialized Scaffold child nodes must always be dictionaries");
 113                }
 114
 49115                if (childDictionary.Count == 0)
 0116                {
 0117                    continue;
 118                }
 119
 49120                var childNode = GetNode(childDictionary);
 45121                childrenList.Add(childNode);
 45122            }
 123
 32124            return childrenList;
 32125        }
 126
 127        private static TemplScaffoldNode GetNode(IDictionary<object, object> childDictionary)
 49128        {
 49129            var firstPair = childDictionary.First();
 130
 49131            var name = firstPair.Key.ToString();
 132
 49133            var nodeInputs = childDictionary
 134                .Skip(1)
 32135                .ToDictionary(p => p.Key.ToString(), p => p.Value);
 136
 49137            var value = firstPair.Value;
 49138            return value is string reference
 139                ? GetFileNode(name, reference, nodeInputs)
 140                : GetDirectoryNode(name, value);
 45141        }
 142
 143        private static TemplScaffoldNode GetDirectoryNode(string name, object value)
 25144        {
 25145            var directoryNode = new TemplScaffoldDirectory() { name = name };
 25146            var directoryChildren = ReadDtoTree(value);
 23147            directoryNode.AddChildrenRange(directoryChildren);
 23148            return directoryNode;
 23149        }
 150
 151        private static TemplScaffoldNode GetFileNode(
 152            string name,
 153            string reference,
 154            IDictionary<string, object> nodeInputs)
 24155        {
 24156            var path = GUID.TryParse(reference, out _)
 157                ? AssetDatabase.GUIDToAssetPath(reference)
 158                : reference;
 159
 24160            if (string.IsNullOrWhiteSpace(path))
 1161            {
 1162                throw new FileNotFoundException(
 163                    $"Could not find template asset with guid '{reference}'");
 164            }
 165
 23166            if (!File.Exists(path))
 1167            {
 1168                throw new FileNotFoundException($"Could not find template asset at {path}");
 169            }
 170
 22171            var template = AssetDatabase.LoadAssetAtPath<ScribanAsset>(path);
 22172            return new TemplScaffoldFile(template) { name = name, NodeInputs = nodeInputs };
 22173        }
 174    }
 175}