static JSettings _Load(string file, Type type, bool useDefault) { JSettings R = null; if (AFile.ExistsAsAny(file)) { try { if (useDefault) { AFile.Delete(file); } else { var b = AFile.LoadBytes(file); var opt = new JsonSerializerOptions { IgnoreNullValues = true, AllowTrailingCommas = true }; R = JsonSerializer.Deserialize(b, type, opt) as JSettings; } } catch (Exception ex) { string es = ex.ToStringWithoutStack(); if (useDefault) { AOutput.Write($"Failed to delete settings file '{file}'. {es}"); } else { string backup = file + ".backup"; try { AFile.Move(file, backup, IfExists.Delete); } catch { backup = "failed"; } AOutput.Write( $@"Failed to load settings from {file}. Will use default settings. {es} Backup: {backup}" ); } } } R ??= Activator.CreateInstance(type) as JSettings; R._file = file; R._loaded = true; //autosave if (Interlocked.Exchange(ref s_loadedOnce, 1) == 0) { AThread.Start(() => { for (; ;) { Thread.Sleep(2000); _SaveAllIfNeed(); } }, sta: false); AProcess.Exit += (unu, sed) => _SaveAllIfNeed(); //info: Core does not call finalizers when process exits } lock (s_list) s_list.Add(R); return(R); }
/// <summary> /// Workaround for DocFX bug: applies markdown in inline code. It can damage whole text. /// Also something more. /// </summary> static void ProcessYamlFile(string path, bool test) { //AOutput.Write(path); try { //var text = File.ReadAllText(path); var yaml = new YamlStream(); using (var fs = File.OpenText(path)) yaml.Load(fs); var root = (YamlMappingNode)yaml.Documents[0].RootNode; var mark = new YamlScalarNode("au"); if (root.Children.ContainsKey(mark)) { return; } bool save = false; foreach (YamlMappingNode item in (YamlSequenceNode)root.Children[new YamlScalarNode("items")]) { foreach (var name in s_names) { if (!item.Children.TryGetValue(name, out var node)) { continue; } //AOutput.Write("----", name, node.NodeType); if (node is YamlScalarNode scalar) //summary, remarks { if (ProcessYamlValue(scalar)) { save = true; } } else if (node is YamlMappingNode map) //syntax { if (map.Children.TryGetValue("parameters", out node)) { foreach (YamlMappingNode par in node as YamlSequenceNode) { if (!par.Children.TryGetValue("description", out node)) { continue; } if (ProcessYamlValue(node as YamlScalarNode)) { save = true; } } } if (map.Children.TryGetValue("return", out node)) { if (!(node as YamlMappingNode).Children.TryGetValue("description", out node)) { continue; } if (ProcessYamlValue(node as YamlScalarNode)) { save = true; } } } else if (node is YamlSequenceNode seq) //exceptions, example { switch (name) { case "example": foreach (var v in seq) { if (ProcessYamlValue(v as YamlScalarNode)) { save = true; } } break; case "exceptions": foreach (YamlMappingNode v in seq) { if (!v.Children.TryGetValue("description", out node)) { continue; } if (ProcessYamlValue(node as YamlScalarNode)) { save = true; } } break; } } } } if (!save) { return; } root.Add(mark, "true"); var tmp = path + ".tmp"; using (var sw = File.CreateText(tmp)) { sw.WriteLine("### YamlMime:ManagedReference"); yaml.Save(sw, false); } if (test) { //AOutput.Write(File.ReadAllText(tmp)); } else { AFile.Move(tmp, path, IfExists.Delete); } } catch (Exception e) { AOutput.Write(e); } }
/// <summary> /// Moves the specified file to the destination. /// </summary> /// <param name="source">The source.</param> /// <param name="destination">The destination.</param> /// <param name="overwrite">if set to <c>true</c> [overwrite].</param> /// <returns>Whether the file was moved or not.</returns> public static bool Move(AFile source, AFile destination, bool overwrite = false) { Exceptions.NotNullException<AFile>(source, nameof(source)); Exceptions.NotNullException<AFile>(destination, nameof(destination)); if ((!overwrite && Fenrir.FileSystem.FileExists(destination.FullPath)) || !Fenrir.FileSystem.FileExists(source.FullPath)) return false; return source.Move(destination.FullPath, FileCollisionOption.ReplaceExisting); }