1 // =================================
  2 // Copyright (c) 2024 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System;
  7 
  8 namespace System.XPath
  9 {
 10     [nodiscard]
 11     public Result<NodeSet*> NodeSetCast(Object* objectFunction* function)
 12     {
 13         if (object->IsNodeSet())
 14         {
 15             return cast<NodeSet*>(object);
 16         }
 17         else
 18         {
 19             int errorId = AllocateError("\'" + function->Name() + "()\' function requires a node-set, " + ObjectKindStr(object->Kind()) + " provided");
 20             return Result<NodeSet*>(ErrorId(errorId));
 21         }
 22     }
 23 
 24     [nodiscard]
 25     public Result<UniquePtr<Object>> EvaluateToString(NodeSet* nodeSet)
 26     {
 27         if (nodeSet->Count() == 0)
 28         {
 29             return Result<UniquePtr<Object>>(UniquePtr<Object>(new Str()));
 30         }
 31         else
 32         {
 33             return Result<UniquePtr<Object>>(UniquePtr<Object>(new Str(StringValue(nodeSet->GetNode(0)))));
 34         }
 35     }
 36 
 37     [nodiscard]
 38     public Result<UniquePtr<Object>> EvaluateToString(Boolean* boolean)
 39     {
 40         if (boolean->Value())
 41         {
 42             return Result<UniquePtr<Object>>(UniquePtr<Object>(new Str("true")));
 43         }
 44         else
 45         {
 46             return Result<UniquePtr<Object>>(UniquePtr<Object>(new Str("false")));
 47         }
 48     }
 49 
 50     [nodiscard]
 51     public Result<UniquePtr<Object>> EvaluateToString(Number* number)
 52     {
 53         return Result<UniquePtr<Object>>(UniquePtr<Object>(new Str(ToString(number->Value()))));
 54     }
 55 
 56     [nodiscard]
 57     public Result<UniquePtr<Object>> EvaluateToString(Str* string)
 58     {
 59         return Result<UniquePtr<Object>>(UniquePtr<Object>(new Str(string->Value())));
 60     }
 61 
 62     [nodiscard]
 63     public Result<UniquePtr<Object>> EvaluateToBoolean(NodeSet* nodeSet)
 64     {
 65         return Result<UniquePtr<Object>>(UniquePtr<Object>(new Boolean(nodeSet->Count() != 0)));
 66     }
 67 
 68     [nodiscard]
 69     public Result<UniquePtr<Object>> EvaluateToBoolean(Boolean* boolean)
 70     {
 71         return Result<UniquePtr<Object>>(UniquePtr<Object>(new Boolean(boolean->Value())));
 72     }
 73 
 74     [nodiscard]
 75     public Result<UniquePtr<Object>> EvaluateToBoolean(Number* number)
 76     {
 77         return Result<UniquePtr<Object>>(UniquePtr<Object>(new Boolean(number->Value() != 0)));
 78     }
 79 
 80     [nodiscard]
 81     public Result<UniquePtr<Object>> EvaluateToBoolean(Str* string)
 82     {
 83         return Result<UniquePtr<Object>>(UniquePtr<Object>(new Boolean(!string->Value().IsEmpty())));
 84     }
 85 
 86     [nodiscard]
 87     public Result<UniquePtr<Object>> EvaluateToNumber(NodeSet* nodeSet)
 88     {
 89         Result<UniquePtr<Object>> stringResult = EvaluateToString(nodeSet);
 90         if (stringResult.Value()->IsString())
 91         {
 92             Str* string = cast<Str*>(stringResult.Value().Get());
 93             return EvaluateToNumber(string);
 94         }
 95         else
 96         {
 97             int errorId = AllocateError("string expected");
 98             return Result<UniquePtr<Object>>(ErrorId(errorId));
 99         }
100     }
101 
102     [nodiscard]
103     public Result<UniquePtr<Object>> EvaluateToNumber(Boolean* boolean)
104     {
105         if (boolean->Value())
106         {
107             return Result<UniquePtr<Object>>(UniquePtr<Object>(new Number(1)));
108         }
109         else
110         {
111             return Result<UniquePtr<Object>>(UniquePtr<Object>(new Number(0)));
112         }
113     }
114 
115     [nodiscard]
116     public Result<UniquePtr<Object>> EvaluateToNumber(Number* number)
117     {
118         return Result<UniquePtr<Object>>(UniquePtr<Object>(new Number(number->Value())));
119     }
120 
121     [nodiscard]
122     public Result<UniquePtr<Object>> EvaluateToNumber(Str* string)
123     {
124         Result<double> result = ParseDouble(string->Value());
125         if (result.Error())
126         {
127             return Result<UniquePtr<Object>>(ErrorId(result.GetErrorId()));
128         }
129         return Result<UniquePtr<Object>>(UniquePtr<Object>(new Number(result.Value())));
130     }
131 }