Files
evening_detective_server/internal/app/story_mapper.go
T
2026-10-03 14:52:40 +07:00

279 lines
6.2 KiB
Go

package app
import (
"bufio"
"strings"
"evening_detective_server/internal/modules/storytelling"
"evening_detective_server/internal/services/scenarios_service"
proto "evening_detective_server/proto"
"google.golang.org/protobuf/types/known/timestamppb"
)
func mapScenarios(o []*scenarios_service.Scenario) []*proto.Scenario {
res := make([]*proto.Scenario, 0, len(o))
for _, item := range o {
res = append(res, mapScenario(item))
}
return res
}
func mapScenario(o *scenarios_service.Scenario) *proto.Scenario {
if o == nil {
return nil
}
var publishedAt *timestamppb.Timestamp
if o.PublishedAt != nil {
publishedAt = timestamppb.New(*o.PublishedAt)
}
return &proto.Scenario{
ID: int32(o.ID),
Name: o.Name,
Description: o.Description,
Image: o.Image,
Story: mapStory(o.Story),
Author: mapUser(o.Author),
Status: o.Status,
UpdatedAt: timestamppb.New(o.UpdatedAt),
CreatedAt: timestamppb.New(o.CreatedAt),
PublishedAt: publishedAt,
AverageRating: o.AverageRating,
ReviewsCount: o.ReviewsCount,
Difficulty: o.Difficulty,
}
}
func mapStory(o *storytelling.Story) *proto.Story {
if o == nil {
return nil
}
return &proto.Story{
Background: o.Background,
Introduction: mapIntroduction(o.Introduction),
Conclusion: mapConclusion(o.Conclusion),
Places: mapPlaces(o.Places),
Questions: mapQuestions(o.Questions),
}
}
func mapConclusion(o *storytelling.Conclusion) *proto.Conclusion {
if o == nil {
return nil
}
return &proto.Conclusion{Text: o.Text, Video: o.Video}
}
func convertConclusion(o *proto.Conclusion) *storytelling.Conclusion {
if o == nil || (o.Text == "" && o.Video == "") {
return nil
}
return &storytelling.Conclusion{Text: formatText(o.Text), Video: o.Video}
}
func mapIntroduction(o *storytelling.Introduction) *proto.Introduction {
if o == nil {
return nil
}
return &proto.Introduction{
Text: o.Text,
Audio: o.Audio,
}
}
func mapPlaces(o []*storytelling.Place) []*proto.Place {
res := make([]*proto.Place, 0, len(o))
for _, item := range o {
res = append(res, mapPlace(item))
}
return res
}
func mapPlace(o *storytelling.Place) *proto.Place {
return &proto.Place{
Code: o.Code,
Name: o.Name,
Text: o.Text,
Image: o.Image,
Hidden: o.Hidden,
Applications: mapApplications(o.Applications),
Doors: mapDoors(o.Doors),
Keys: mapKeys(o.Keys),
}
}
func mapApplications(o []*storytelling.Application) []*proto.Application {
res := make([]*proto.Application, 0, len(o))
for _, item := range o {
res = append(res, mapApplication(item))
}
return res
}
func mapDoors(o []*storytelling.Door) []*proto.Door {
res := make([]*proto.Door, 0, len(o))
for _, item := range o {
res = append(res, mapDoor(item))
}
return res
}
func mapKeys(o []*storytelling.Key) []*proto.Key {
res := make([]*proto.Key, 0, len(o))
for _, item := range o {
res = append(res, mapKey(item))
}
return res
}
func mapApplication(o *storytelling.Application) *proto.Application {
return &proto.Application{
Name: o.Name,
Image: o.Image,
FileType: o.FileType,
}
}
func mapDoor(o *storytelling.Door) *proto.Door {
return &proto.Door{
Code: o.Code,
Name: o.Name,
Keys: mapKeys(o.Keys),
}
}
func mapKey(o *storytelling.Key) *proto.Key {
return &proto.Key{
Name: o.Name,
}
}
func convertPlace(o *proto.Place) *storytelling.Place {
return &storytelling.Place{
Code: o.Code,
Name: formatString(o.Name),
Text: formatText(o.Text),
Image: o.Image,
Hidden: o.Hidden,
Applications: convertApplications(o.Applications),
Doors: convertDoors(o.Doors),
Keys: convertKeys(o.Keys),
}
}
func convertApplications(o []*proto.Application) []*storytelling.Application {
res := make([]*storytelling.Application, 0, len(o))
for _, item := range o {
res = append(res, convertApplication(item))
}
return res
}
func convertDoors(o []*proto.Door) []*storytelling.Door {
res := make([]*storytelling.Door, 0, len(o))
for _, item := range o {
res = append(res, convertDoor(item))
}
return res
}
func convertKeys(o []*proto.Key) []*storytelling.Key {
res := make([]*storytelling.Key, 0, len(o))
for _, item := range o {
res = append(res, convertKey(item))
}
return res
}
func convertApplication(o *proto.Application) *storytelling.Application {
return &storytelling.Application{
Name: formatString(o.Name),
Image: o.Image,
FileType: o.FileType,
}
}
func convertDoor(o *proto.Door) *storytelling.Door {
return &storytelling.Door{
Code: o.Code,
Name: formatString(o.Name),
Keys: convertKeys(o.Keys),
}
}
func convertKey(o *proto.Key) *storytelling.Key {
return &storytelling.Key{
Name: formatString(o.Name),
}
}
func convertIntroduction(o *proto.Introduction) *storytelling.Introduction {
if o == nil || (o.Text == "" && o.Audio == "") {
return nil
}
return &storytelling.Introduction{
Text: formatText(o.Text),
Audio: o.Audio,
}
}
func mapQuestions(o []*storytelling.Question) []*proto.Question {
res := make([]*proto.Question, 0, len(o))
for _, item := range o {
res = append(res, mapQuestion(item))
}
return res
}
func mapQuestion(o *storytelling.Question) *proto.Question {
if o == nil {
return nil
}
return &proto.Question{
Code: o.Code,
Text: o.Text,
Answer: o.Answer,
}
}
func convertQuestion(o *proto.Question) *storytelling.Question {
if o == nil {
return nil
}
return &storytelling.Question{
Code: o.Code,
Text: formatText(o.Text),
Answer: formatText(o.Answer),
}
}
func formatText(text string) string {
scanner := bufio.NewScanner(strings.NewReader(text))
var result strings.Builder
for i := 0; scanner.Scan(); i++ {
line := strings.TrimSpace(scanner.Text())
if strings.HasPrefix(line, "--") {
line = strings.Replace(line, "--", "—", 1)
}
if i == 0 && strings.HasPrefix(line, "—") {
result.WriteString(" ")
}
if i > 0 {
result.WriteByte('\n')
if line != "" {
result.WriteString(" ")
}
}
result.WriteString(line)
}
return result.String()
}
func formatString(text string) string {
text = strings.TrimSpace(text)
if strings.HasPrefix(text, "--") {
text = strings.Replace(text, "--", "—", 1)
}
return text
}