Skip to content

Commit 1ef7129

Browse files
author
e.ivanov
committed
сериализация
1 parent f3448c0 commit 1ef7129

8 files changed

+599
-187
lines changed

src/internal/Модули/ПарсерКлючЗначение.os

Lines changed: 71 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
КонецЦикла;
7474
КонецПроцедуры
7575

76-
// Находит позицию двоеточия, игнорируя двоеточия внутри кавычек
76+
// Находит позицию двоеточия, игнорируя двоеточия внутри кавычек или строковых значений
7777
//
7878
// Параметры:
7979
// Строка - Строка - строка для поиска
@@ -88,22 +88,78 @@
8888
Для Позиция = 1 По СтрДлина(Строка) Цикл
8989
Символ = Сред(Строка, Позиция, 1);
9090

91-
Если НЕ ВКавычках Тогда
92-
Если Символ = """" ИЛИ Символ = "'" Тогда
93-
ВКавычках = Истина;
94-
ТипКавычек = Символ;
95-
КонецЕсли;
96-
97-
Если Символ = ":" Тогда
98-
Возврат Позиция;
99-
КонецЕсли;
100-
Иначе
101-
Если Символ = ТипКавычек Тогда
102-
ВКавычках = Ложь;
103-
ТипКавычек = "";
104-
КонецЕсли;
91+
// Обработка состояния "в кавычках"
92+
Если ОбработатьКавычки(Символ, ВКавычках, ТипКавычек) Тогда
93+
Продолжить;
94+
КонецЕсли;
95+
96+
// Если мы внутри кавычек, пропускаем проверку двоеточия
97+
Если ВКавычках Тогда
98+
Продолжить;
99+
КонецЕсли;
100+
101+
// Проверка на двоеточие
102+
Если Символ = ":" И ЭтоРазделительДвоеточие(Строка, Позиция) Тогда
103+
Возврат Позиция;
105104
КонецЕсли;
106105
КонецЦикла;
107106

108107
Возврат 0;
109108
КонецФункции
109+
110+
// Обрабатывает кавычки и обновляет состояние "в кавычках"
111+
//
112+
// Параметры:
113+
// Символ - Строка - текущий символ
114+
// ВКавычках - Булево - состояние "в кавычках" (передается по ссылке)
115+
// ТипКавычек - Строка - тип кавычек (передается по ссылке)
116+
//
117+
// Возвращаемое значение:
118+
// Булево - Истина, если символ был кавычкой и обработан
119+
//
120+
Функция ОбработатьКавычки(Символ, ВКавычках, ТипКавычек)
121+
Если Символ <> """" И Символ <> "'" Тогда
122+
Возврат Ложь;
123+
КонецЕсли;
124+
125+
Если НЕ ВКавычках Тогда
126+
ВКавычках = Истина;
127+
ТипКавычек = Символ;
128+
Иначе
129+
Если Символ = ТипКавычек Тогда
130+
ВКавычках = Ложь;
131+
ТипКавычек = "";
132+
КонецЕсли;
133+
КонецЕсли;
134+
135+
Возврат Истина;
136+
КонецФункции
137+
138+
// Проверяет, является ли двоеточие в указанной позиции разделителем ключ-значение
139+
//
140+
// Параметры:
141+
// Строка - Строка - исходная строка
142+
// Позиция - Число - позиция двоеточия
143+
//
144+
// Возвращаемое значение:
145+
// Булево - Истина, если двоеточие является разделителем
146+
//
147+
Функция ЭтоРазделительДвоеточие(Строка, Позиция)
148+
// Проверка, что после двоеточия идет пробел или конец строки
149+
Если Позиция < СтрДлина(Строка) Тогда
150+
СледующийСимвол = Сред(Строка, Позиция + 1, 1);
151+
Если СледующийСимвол <> " " И СледующийСимвол <> Символы.Таб Тогда
152+
Возврат Ложь;
153+
КонецЕсли;
154+
КонецЕсли;
155+
156+
// Проверка, что перед двоеточием нет пробела
157+
Если Позиция > 1 Тогда
158+
ПредыдущийСимвол = Сред(Строка, Позиция - 1, 1);
159+
Если ПредыдущийСимвол = " " ИЛИ ПредыдущийСимвол = Символы.Таб Тогда
160+
Возврат Ложь;
161+
КонецЕсли;
162+
КонецЕсли;
163+
164+
Возврат Истина;
165+
КонецФункции

src/internal/Модули/ПарсерМассивов.os

Lines changed: 275 additions & 86 deletions
Large diffs are not rendered by default.

src/internal/Модули/Сериализатор.os

Lines changed: 19 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,8 @@
2121
Возврат СериализоватьБулево(Значение);
2222
ИначеЕсли ТипЗначения = Тип("Массив") Тогда
2323
Возврат СериализоватьМассив(Значение, УровеньОтступа);
24-
ИначеЕсли ТипЗначения = Тип("Структура") Тогда
25-
Возврат СериализоватьСтруктуру(Значение, УровеньОтступа);
26-
ИначеЕсли ТипЗначения = Тип("Соответствие") Тогда
27-
Возврат СериализоватьСоответствие(Значение, УровеньОтступа);
24+
ИначеЕсли ТипЗначения = Тип("Структура") Или ТипЗначения = Тип("Соответствие") Тогда
25+
Возврат СериализоватьОбъект(Значение, УровеньОтступа);
2826
ИначеЕсли Значение = Неопределено Тогда
2927
Возврат "null";
3028
ИначеЕсли ТипЗначения = Тип("Дата") Тогда
@@ -127,117 +125,54 @@
127125
Отступ = ПолучитьОтступ(УровеньОтступа);
128126

129127
Для Каждого Элемент Из Массив Цикл
130-
Если Результат <> "" Тогда
131-
Результат = Результат + Символы.ПС;
132-
КонецЕсли;
128+
Результат = Результат + Символы.ПС;
133129

134130
СериализованныйЭлемент = Сериализовать(Элемент, УровеньОтступа + 1);
135-
136-
// Если элемент многострочный, добавляем отступ к каждой строке
137-
Если СтрНайти(СериализованныйЭлемент, Символы.ПС) > 0 Тогда
138-
СтрокиЭлемента = СтрРазделить(СериализованныйЭлемент, Символы.ПС);
139-
ПерваяСтрока = Истина;
140-
Для Каждого СтрокаЭлемента Из СтрокиЭлемента Цикл
141-
Если ПерваяСтрока Тогда
142-
Результат = Результат + Отступ + "- " + СтрокаЭлемента;
143-
ПерваяСтрока = Ложь;
144-
Иначе
145-
Результат = Результат + Символы.ПС + ПолучитьОтступ(УровеньОтступа + 1) + СтрокаЭлемента;
146-
КонецЕсли;
147-
КонецЦикла;
148-
Иначе
149-
Результат = Результат + Отступ + "- " + СериализованныйЭлемент;
150-
КонецЕсли;
151-
КонецЦикла;
152-
153-
Возврат Результат;
154-
155-
КонецФункции
131+
МассивСтрок = СтрРазделить(СериализованныйЭлемент, Символы.ПС, Ложь);
132+
СериализованныйЭлемент = "";
133+
ОтступВложения = ПолучитьОтступ(УровеньОтступа + 1);
134+
Для каждого Строка Из МассивСтрок Цикл
135+
СериализованныйЭлемент = СериализованныйЭлемент + ?(ЗначениеЗаполнено(СериализованныйЭлемент), Символы.ПС + ОтступВложения, Отступ + "- ") + СокрЛП(Строка);
136+
КонецЦикла;
137+
// Убираем последний отступ
138+
СериализованныйЭлемент = СокрП(СериализованныйЭлемент);
139+
Результат = Результат + СериализованныйЭлемент;
156140

157-
// Сериализация структуры
158-
//
159-
// Параметры:
160-
// Структура - Структура - структура для сериализации
161-
// УровеньОтступа - Число - текущий уровень отступа
162-
//
163-
// Возвращаемое значение:
164-
// Строка - YAML представление структуры
165-
//
166-
Функция СериализоватьСтруктуру(Структура, УровеньОтступа = 0)
167-
168-
Если Структура.Количество() = 0 Тогда
169-
Возврат "{}";
170-
КонецЕсли;
171-
172-
Результат = "";
173-
Отступ = ПолучитьОтступ(УровеньОтступа);
174-
175-
Для Каждого КлючЗначение Из Структура Цикл
176-
Если Результат <> "" Тогда
177-
Результат = Результат + Символы.ПС;
178-
КонецЕсли;
179-
180-
Ключ = КлючЗначение.Ключ;
181-
Значение = КлючЗначение.Значение;
182-
183-
СериализованныйКлюч = СериализоватьКлюч(Ключ);
184-
СериализованноеЗначение = Сериализовать(Значение, УровеньОтступа + 1);
185-
186-
// Если значение многострочное, добавляем отступ к каждой строке кроме первой
187-
Если СтрНайти(СериализованноеЗначение, Символы.ПС) > 0 Тогда
188-
СтрокиЗначения = СтрРазделить(СериализованноеЗначение, Символы.ПС);
189-
Результат = Результат + Отступ + СериализованныйКлюч + ":";
190-
Для Каждого СтрокаЗначения Из СтрокиЗначения Цикл
191-
Результат = Результат + Символы.ПС + ПолучитьОтступ(УровеньОтступа + 1) + СтрокаЗначения;
192-
КонецЦикла;
193-
Иначе
194-
Результат = Результат + Отступ + СериализованныйКлюч + ": " + СериализованноеЗначение;
195-
КонецЕсли;
196141
КонецЦикла;
197142

198143
Возврат Результат;
199144

200145
КонецФункции
201146

202-
// Сериализация соответствия
147+
// Сериализация объекта
203148
//
204149
// Параметры:
205-
// Соответствие - Соответствие - соответствие для сериализации
150+
// Объект - Соответствие, Структура - соответствие для сериализации
206151
// УровеньОтступа - Число - текущий уровень отступа
207152
//
208153
// Возвращаемое значение:
209154
// Строка - YAML представление соответствия
210155
//
211-
Функция СериализоватьСоответствие(Соответствие, УровеньОтступа = 0)
156+
Функция СериализоватьОбъект(Объект, УровеньОтступа = 0)
212157

213-
Если Соответствие.Количество() = 0 Тогда
158+
Если Объект.Количество() = 0 Тогда
214159
Возврат "{}";
215160
КонецЕсли;
216161

217162
Результат = "";
218163
Отступ = ПолучитьОтступ(УровеньОтступа);
219164

220-
Для Каждого КлючЗначение Из Соответствие Цикл
221-
Если Результат <> "" Тогда
222-
Результат = Результат + Символы.ПС;
223-
КонецЕсли;
165+
Для Каждого КлючЗначение Из Объект Цикл
166+
Результат = Результат + Символы.ПС;
224167

225168
Ключ = КлючЗначение.Ключ;
226169
Значение = КлючЗначение.Значение;
227170

228171
СериализованныйКлюч = СериализоватьКлюч(Ключ);
229172
СериализованноеЗначение = Сериализовать(Значение, УровеньОтступа + 1);
230173

231-
// Если значение многострочное, добавляем отступ к каждой строке кроме первой
232-
Если СтрНайти(СериализованноеЗначение, Символы.ПС) > 0 Тогда
233-
СтрокиЗначения = СтрРазделить(СериализованноеЗначение, Символы.ПС);
234-
Результат = Результат + Отступ + СериализованныйКлюч + ":";
235-
Для Каждого СтрокаЗначения Из СтрокиЗначения Цикл
236-
Результат = Результат + Символы.ПС + ПолучитьОтступ(УровеньОтступа + 1) + СтрокаЗначения;
237-
КонецЦикла;
238-
Иначе
174+
239175
Результат = Результат + Отступ + СериализованныйКлюч + ": " + СериализованноеЗначение;
240-
КонецЕсли;
241176
КонецЦикла;
242177

243178
Возврат Результат;

src/Классы/ПарсерYaml.os

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,7 @@
210210

211211
// Определяем тип элемента и обрабатываем его
212212
Если ПарсерУровней.ЭтоЭлементМассива(ОчищеннаяСтрока) Тогда
213-
ПарсерМассивов.ОбработатьЭлементМассива(ОчищеннаяСтрока, ТекущийКонтекст, СтекКонтекстов, МенеджерЯкорей);
214-
Возврат 1;
213+
Возврат ПарсерМассивов.ОбработатьЭлементМассива(ОчищеннаяСтрока, ТекущийКонтекст, СтекКонтекстов, МенеджерЯкорей, Строки, Индекс);
215214
Иначе
216215
Возврат ОбработатьКлючЗначение(ОчищеннаяСтрока, ТекущийКонтекст, СтекКонтекстов, Строки, Индекс);
217216
КонецЕсли;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
volumes:
2+
- sonarr_config:
3+
test: /config
4+
test2: /downloads
5+
- media:/plex_media
6+
- transmission_download:/downloads
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#Использовать asserts
2+
#Использовать ".."
3+
#Использовать "."
4+
5+
&ТестовыйНабор
6+
Процедура ПриСозданииОбъекта() Экспорт
7+
КонецПроцедуры
8+
9+
&Тест
10+
Процедура ТестПарсингаВложенныхОбъектовВМассиве() Экспорт
11+
// Дано
12+
СодержимоеФайла = ТестовыеУтилиты.ПрочитатьТекстФайла(ТестовыеУтилиты.ПолучитьПутьКТестовымДанным("nested_array_object.yaml"));
13+
ЧтениеYaml = ТестовыеУтилиты.СоздатьЭкземплярПарсера();
14+
15+
// Когда
16+
Результат = ЧтениеYaml.ПрочитатьYaml(СодержимоеФайла);
17+
18+
// Тогда
19+
Ожидаем.Что(Результат).Не_().ЭтоНеопределено();
20+
21+
Volumes = Результат.Получить("volumes");
22+
Ожидаем.Что(Volumes).Не_().ЭтоНеопределено();
23+
Ожидаем.Что(Volumes.Количество()).Равно(3);
24+
25+
// Первый элемент должен быть соответствием с вложенной структурой
26+
ПервыйЭлемент = Volumes[0];
27+
Ожидаем.Что(ТипЗнч(ПервыйЭлемент)).Равно(Тип("Соответствие"));
28+
29+
SonarrConfig = ПервыйЭлемент.Получить("sonarr_config");
30+
Ожидаем.Что(SonarrConfig).Не_().ЭтоНеопределено();
31+
Ожидаем.Что(ТипЗнч(SonarrConfig)).Равно(Тип("Соответствие"));
32+
Ожидаем.Что(SonarrConfig.Получить("test")).Равно("/config");
33+
Ожидаем.Что(SonarrConfig.Получить("test2")).Равно("/downloads");
34+
35+
// Второй и третий элементы должны быть строками
36+
Ожидаем.Что(Volumes[1]).Равно("media:/plex_media");
37+
Ожидаем.Что(Volumes[2]).Равно("transmission_download:/downloads");
38+
КонецПроцедуры

0 commit comments

Comments
 (0)